2016-01-26 09:29:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  MinIO  Cloud  Storage ,  ( C )  2016 - 2019  MinIO ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-26 09:29:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:27:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/xml" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-06 01:48:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"net/url" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-22 14:38:38 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"runtime" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"strconv" 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"strings" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/gorilla/mux" 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-13 10:55:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/gorilla/rpc/v2/json2" 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 14:08:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/klauspost/compress/zip" 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 07:35:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									miniogopolicy  "github.com/minio/minio-go/v6/pkg/policy" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio-go/v6/pkg/s3utils" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 10:07:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/browser" 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-26 08:33:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/config/etcd/dns" 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/config/identity/openid" 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/crypto" 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									xhttp  "github.com/minio/minio/cmd/http" 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/auth" 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-28 06:12:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectlock  "github.com/minio/minio/pkg/bucket/object/lock" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/bucket/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/event" 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-06 02:20:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/handlers" 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/hash" 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									iampolicy  "github.com/minio/minio/pkg/iam/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/ioutil" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-08 14:44:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// WebGenericArgs - empty struct for calls that don't accept arguments
  
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// for ex. ServerInfo, GenerateAuth
  
						 
					
						
							
								
									
										
										
										
											2016-04-08 14:44:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  WebGenericArgs  struct { }  
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-08 14:44:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// WebGenericRep - reply structure for calls for which reply is success/failure
  
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// for ex. RemoveObject MakeBucket
  
						 
					
						
							
								
									
										
										
										
											2016-04-08 14:44:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  WebGenericRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ServerInfoRep - server info reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ServerInfoRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2017-05-25 12:09:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MinioVersion     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MinioMemory      string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MinioPlatform    string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MinioRuntime     string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									MinioGlobalInfo  map [ string ] interface { } 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									MinioUserInfo    map [ string ] interface { } 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-25 12:09:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									UIVersion        string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ServerInfo - get server info.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  ServerInfo ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * ServerInfoRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebServerInfo" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									host ,  err  :=  os . Hostname ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									platform  :=  fmt . Sprintf ( "Host: %s | OS: %s | Arch: %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . GOOS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . GOARCH ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									goruntime  :=  fmt . Sprintf ( "Version: %s | CPUs: %d" ,  runtime . Version ( ) ,  runtime . NumCPU ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-04 04:47:03 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-19 07:23:42 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									reply . MinioVersion  =  Version 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-25 12:09:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . MinioGlobalInfo  =  getGlobalInfo ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if the user is IAM user.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . MinioUserInfo  =  map [ string ] interface { } { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"isIAMUser" :  ! owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! owner  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creds ,  ok  :=  globalIAMSys . GetUser ( claims . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ok  &&  creds . SessionToken  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reply . MinioUserInfo [ "isTempUser" ]  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-09 04:40:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									reply . MinioPlatform  =  platform 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . MinioRuntime  =  goruntime 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-27 05:13:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// StorageInfoRep - contains storage usage statistics.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  StorageInfoRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2020-06-10 06:05:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Used       uint64  ` json:"used" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-27 05:13:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// StorageInfo - web call to gather storage usage statistics.
  
						 
					
						
							
								
									
										
										
										
											2019-04-18 14:16:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  StorageInfo ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * StorageInfoRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebStorageInfo" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  _ ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-10 06:05:39 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dataUsageInfo ,  _  :=  loadDataUsageFromBackend ( ctx ,  objectAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . Used  =  dataUsageInfo . ObjectsTotalSize 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-27 05:13:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// MakeBucketArgs - make bucket args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  MakeBucketArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// MakeBucket - creates a new bucket.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  MakeBucket ( r  * http . Request ,  args  * MakeBucketArgs ,  reply  * WebGenericRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebMakeBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . CreateBucketAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-09-02 03:16:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 02:42:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  true )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  err  :=  globalDNSConfig . Get ( args . BucketName ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-13 05:12:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Proceed to creating a bucket.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  =  objectAPI . MakeBucketWithLocation ( ctx ,  args . BucketName ,  globalServerRegion ,  false ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  globalDNSConfig . Put ( args . BucketName ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 12:52:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													objectAPI . DeleteBucket ( ctx ,  args . BucketName ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errBucketAlreadyExists ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  objectAPI . MakeBucketWithLocation ( ctx ,  args . BucketName ,  globalServerRegion ,  false ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-13 10:55:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-13 10:55:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-25 14:26:53 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RemoveBucketArgs - remove bucket args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  RemoveBucketArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// DeleteBucket - removes a bucket, must be empty.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  DeleteBucket ( r  * http . Request ,  args  * RemoveBucketArgs ,  reply  * WebGenericRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebDeleteBucket" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . DeleteBucketAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										core ,  err  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  core . RemoveBucket ( args . BucketName ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									deleteBucket  :=  objectAPI . DeleteBucket 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-28 12:52:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  deleteBucket ( ctx ,  args . BucketName ,  false ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  globalDNSConfig . Delete ( args . BucketName ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Deleting DNS entry failed, attempt to create the bucket again.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-09 04:44:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											objectAPI . MakeBucketWithLocation ( ctx ,  args . BucketName ,  "" ,  false ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									globalNotificationSys . DeleteBucketMetadata ( ctx ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-30 00:56:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 21:15:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ListBucketsRep - list buckets response
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ListBucketsRep  struct  {  
						 
					
						
							
								
									
										
										
											
												objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
											 
										 
										
											2016-04-03 16:34:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									Buckets    [ ] WebBucketInfo  ` json:"buckets" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string           ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
											 
										 
										
											2016-04-03 16:34:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// WebBucketInfo container for list buckets metadata.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  WebBucketInfo  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// The name of the bucket.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Name  string  ` json:"name" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Date the bucket was created.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CreationDate  time . Time  ` json:"creationDate" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ListBuckets - list buckets api.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  ListBuckets ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * ListBucketsRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebListBuckets" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									listBuckets  :=  objectAPI . ListBuckets 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-20 15:20:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set prefix value for "s3:prefix" policy conditionals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									r . Header . Set ( "prefix" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set delimiter value for "s3:delimiter" policy conditionals.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									r . Header . Set ( "delimiter" ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-20 15:20:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If etcd, dns federation configured list buckets from etcd.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 11:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalDNSConfig  !=  nil  &&  globalBucketFederation  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dnsBuckets ,  err  :=  globalDNSConfig . List ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-13 08:57:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  &&  err  !=  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  dnsRecords  :=  range  dnsBuckets  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . ListBucketAction , 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BucketName :       dnsRecords [ 0 ] . Key , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       "" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reply . Buckets  =  append ( reply . Buckets ,  WebBucketInfo { 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-03 16:24:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Name :          dnsRecords [ 0 ] . Key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													CreationDate :  dnsRecords [ 0 ] . CreationDate , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										buckets ,  err  :=  listBuckets ( ctx ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  bucket  :=  range  buckets  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-14 05:03:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . ListAllMyBucketsAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BucketName :       bucket . Name , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       "" , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-11 01:27:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reply . Buckets  =  append ( reply . Buckets ,  WebBucketInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Name :          bucket . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													CreationDate :  bucket . Created , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-02 01:36:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ListObjectsArgs - list object args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ListObjectsArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix      string  ` json:"prefix" ` 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-11 14:54:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Marker      string  ` json:"marker" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListObjectsRep - list objects response.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ListObjectsRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Objects    [ ] WebObjectInfo  ` json:"objects" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Writable   bool             ` json:"writable" `  // Used by client to show "upload file" button.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string           ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												objectAPI: Fix object API interface, remove unnecessary structs.
ObjectAPI changes.
```
ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsInfo, *probe.Error)
ListMultipartUploads(bucket, objectPrefix, keyMarker, uploadIDMarker, delimiter string, maxUploads int) (ListMultipartsInfo, *probe.Error)
ListObjectParts(bucket, object, uploadID string, partNumberMarker, maxParts int) (ListPartsInfo, *probe.Error)
CompleteMultipartUpload(bucket string, object string, uploadID string, parts []completePart) (ObjectInfo, *probe.Error)
```
											 
										 
										
											2016-04-03 16:34:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// WebObjectInfo container for list objects metadata.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  WebObjectInfo  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Name of the object
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Key  string  ` json:"name" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Date and time the object was last modified.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									LastModified  time . Time  ` json:"lastModified" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Size in bytes of the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Size  int64  ` json:"size" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// ContentType is mime type of the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ContentType  string  ` json:"contentType" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// ListObjects - list objects api.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  ListObjects ( r  * http . Request ,  args  * ListObjectsArgs ,  reply  * ListObjectsRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebListObjects" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-29 05:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									listObjects  :=  objectAPI . ListObjects 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										core ,  err  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nextMarker  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Fetch all the objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 07:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Let listObjects reply back the maximum from server implementation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											result ,  err  :=  core . ListObjects ( args . BucketName ,  args . Prefix ,  nextMarker ,  SlashSeparator ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  obj  :=  range  result . Contents  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reply . Objects  =  append ( reply . Objects ,  WebObjectInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Key :           obj . Key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													LastModified :  obj . LastModified , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Size :          obj . Size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ContentType :   obj . ContentType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  p  :=  range  result . CommonPrefixes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												reply . Objects  =  append ( reply . Objects ,  WebObjectInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Key :  p . Prefix , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nextMarker  =  result . NextMarker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Return when there are no more objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! result . IsTruncated  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-20 15:20:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Set prefix value for "s3:prefix" policy conditionals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											r . Header . Set ( "prefix" ,  args . Prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Set delimiter value for "s3:delimiter" policy conditionals.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											r . Header . Set ( "delimiter" ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Check if anonymous (non-owner) has access to download objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											readable  :=  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           policy . ListBucketAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if anonymous (non-owner) has access to upload objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writable  :=  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           policy . PutObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ObjectName :       args . Prefix  +  SlashSeparator , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reply . Writable  =  writable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! readable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Error out if anonymous user (non-owner) has no access to download or upload objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! writable  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  errAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// return empty object list if access is write only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-20 15:20:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Set prefix value for "s3:prefix" policy conditionals.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										r . Header . Set ( "prefix" ,  args . Prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Set delimiter value for "s3:delimiter" policy conditionals.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r . Header . Set ( "delimiter" ,  SlashSeparator ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										readable  :=  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . ListBucketAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writable  :=  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . PutObjectAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ObjectName :       args . Prefix  +  SlashSeparator , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-01 04:20:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reply . Writable  =  writable 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! readable  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Error out if anonymous user (non-owner) has no access to download or upload objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! writable  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  errAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-01 04:20:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// return empty object list if access is write only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									nextMarker  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Fetch all the objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 07:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Limit browser to 1000 batches to be more responsive, scrolling friendly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										lo ,  err  :=  listObjects ( ctx ,  args . BucketName ,  args . Prefix ,  nextMarker ,  SlashSeparator ,  1000 ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & json2 . Error { Message :  err . Error ( ) } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  i  :=  range  lo . Objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 02:19:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											lo . Objects [ i ] . Size ,  err  =  lo . Objects [ i ] . GetActualSize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-11 14:54:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-26 07:31:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  obj  :=  range  lo . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reply . Objects  =  append ( reply . Objects ,  WebObjectInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Key :           obj . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												LastModified :  obj . ModTime , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Size :          obj . Size , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ContentType :   obj . ContentType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  prefix  :=  range  lo . Prefixes  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reply . Objects  =  append ( reply . Objects ,  WebObjectInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Key :  prefix , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										nextMarker  =  lo . NextMarker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Return when there are no more objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! lo . IsTruncated  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RemoveObjectArgs - args to remove an object, JSON will look like.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// {
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     "bucketname": "testbucket",
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     "objects": [
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//         "photos/hawaii/",
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//         "photos/maldives/",
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//         "photos/sanjose.jpg"
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//     ]
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// }
  
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								type  RemoveObjectArgs  struct  {  
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Objects     [ ] string  ` json:"objects" `     // Contains objects, prefixes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string    ` json:"bucketname" `  // Contains bucket name.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// RemoveObject - removes an object, or all the objects at a given prefix.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  RemoveObject ( r  * http . Request ,  args  * RemoveObjectArgs ,  reply  * WebGenericRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebRemoveObject" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getObjectInfo  :=  objectAPI . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  web . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										getObjectInfo  =  web . CacheAPI ( ) . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									deleteObjects  :=  objectAPI . DeleteObjects 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  web . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deleteObjects  =  web . CacheAPI ( ) . DeleteObjects 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if all objects are allowed to be deleted anonymously
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . DeleteObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  toJSONError ( ctx ,  errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  args . BucketName  ==  ""  ||  len ( args . Objects )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidArgument ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										core ,  err  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objectsCh  :=  make ( chan  string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Send object names that are needed to be removed to objectsCh
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										go  func ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											defer  close ( objectsCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  objectName  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												objectsCh  <-  objectName 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  resp  :=  range  core . RemoveObjects ( args . BucketName ,  objectsCh )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  resp . Err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  resp . Err ,  args . BucketName ,  resp . ObjectName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  err  error 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								next :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  objectName  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// If not a directory, remove the object.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! HasSuffix ( objectName ,  SlashSeparator )  &&  objectName  !=  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// Check permissions for non-anonymous user.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											govBypassPerms  :=  false 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  authErr  !=  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Action :           iampolicy . DeleteObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       objectName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-22 22:54:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Action :           iampolicy . BypassGovernanceRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													govBypassPerms  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Check if object is allowed to be deleted anonymously.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 12:21:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . DeleteObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												// Check if object is allowed to be deleted anonymously
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . BypassGovernanceRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													govBypassPerms  =  true 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											apiErr  :=  enforceRetentionBypassForDeleteWeb ( ctx ,  r ,  args . BucketName ,  objectName ,  getObjectInfo ,  govBypassPerms ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-07 12:31:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  apiErr  ==  ErrObjectLocked  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  errLockedObject ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-04 05:01:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  apiErr  !=  ErrNone  &&  apiErr  !=  ErrNoSuchKey  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  apiErr  ==  ErrNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  =  deleteObject ( ctx ,  objectAPI ,  web . CacheAPI ( ) ,  args . BucketName ,  objectName ,  r ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break  next 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-03-10 12:21:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if object is allowed to be deleted anonymously
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           iampolicy . DeleteObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           iampolicy . DeleteObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       objectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Allocate new results channel to receive ObjectInfo.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										objInfoCh  :=  make ( chan  ObjectInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Walk through all objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  objectAPI . Walk ( ctx ,  args . BucketName ,  objectName ,  objInfoCh ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break  next 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  objects  [ ] string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  obj  :=  range  objInfoCh  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 07:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  len ( objects )  ==  maxDeleteList  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													// Reached maximum delete requests, attempt a delete for now.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												objects  =  append ( objects ,  obj . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Nothing to do.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  len ( objects )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break  next 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Deletes a list of objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											_ ,  err  =  deleteObjects ( ctx ,  args . BucketName ,  objects ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break  next 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 07:02:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-13 10:55:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 23:42:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  &&  ! isErrObjectNotFound ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Ignore object not found error.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ,  args . BucketName ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 23:42:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-13 10:55:17 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-05 22:16:36 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-19 16:00:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// LoginArgs - login arguments.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  LoginArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Username  string  ` json:"username" form:"username" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Password  string  ` json:"password" form:"password" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// LoginRep - login reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  LoginRep  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Token      string  ` json:"token" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Login - user login handler.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  Login ( r  * http . Request ,  args  * LoginArgs ,  reply  * LoginRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebLogin" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									token ,  err  :=  authenticateWeb ( args . Username ,  args . Password ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 12:57:40 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 12:57:40 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . Token  =  token 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 12:57:40 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GenerateAuthReply - reply for GenerateAuth
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  GenerateAuthReply  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccessKey  string  ` json:"accessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SecretKey  string  ` json:"secretKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  webAPIHandlers )  GenerateAuth ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * GenerateAuthReply )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebGenerateAuth" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! owner  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-20 08:24:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred ,  err  :=  auth . GetNewCredentials ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-15 01:17:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-15 01:17:07 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . AccessKey  =  cred . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . SecretKey  =  cred . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetAuthArgs - argument for SetAuth
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SetAuthArgs  struct  {  
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									CurrentAccessKey  string  ` json:"currentAccessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									CurrentSecretKey  string  ` json:"currentSecretKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NewAccessKey      string  ` json:"newAccessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NewSecretKey      string  ` json:"newSecretKey" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetAuthReply - reply for SetAuth
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SetAuthReply  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Token        string             ` json:"token" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion    string             ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									PeerErrMsgs  map [ string ] string  ` json:"peerErrMsgs" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetAuth - Set accessKey and secretKey credentials.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  SetAuth ( r  * http . Request ,  args  * SetAuthArgs ,  reply  * SetAuthReply )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebSetAuth" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  owner  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Owner is not allowed to change credentials through browser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errChangeCredNotAllowed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// for IAM users, access key cannot be updated
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// claims.AccessKey is used instead of accesskey from args
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									prevCred ,  ok  :=  globalIAMSys . GetUser ( claims . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errInvalidAccessKeyID 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Throw error when wrong secret key is provided
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  prevCred . SecretKey  !=  args . CurrentSecretKey  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errIncorrectCreds 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									creds ,  err  :=  auth . CreateCredentials ( claims . AccessKey ,  args . NewSecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 20:14:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									err  =  globalIAMSys . SetUserSecretKey ( creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . Token ,  err  =  authenticateWeb ( creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-30 04:18:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-07-25 03:46:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// URLTokenReply contains the reply for CreateURLToken.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  URLTokenReply  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Token      string  ` json:"token" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// CreateURLToken creates a URL token (short-lived) for GET requests.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  CreateURLToken ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * URLTokenReply )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebCreateURLToken" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-25 03:46:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									creds  :=  globalActiveCred 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! owner  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ok  bool 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creds ,  ok  =  globalIAMSys . GetUser ( claims . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  errInvalidAccessKeyID ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-25 03:46:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  creds . SessionToken  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Use the same session token for URL token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . Token  =  creds . SessionToken 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										token ,  err  :=  authenticateURL ( creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . Token  =  token 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-25 03:46:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Upload - file upload handler.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  Upload ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "WebUpload" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// obtain the claims here if possible, for audit logging.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  logger . AuditLog ( w ,  r ,  "WebUpload" ,  claims . Map ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-12 11:38:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									object ,  err  :=  url . PathUnescape ( vars [ "object" ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retPerms  :=  ErrAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									holdPerms  :=  ErrAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if anonymous (non-owner) has access to upload objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           policy . PutObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . PutObjectAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . PutObjectRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											retPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . PutObjectLegalHoldAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											holdPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( bucket ,  false )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-02-05 17:42:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket encryption is enabled
 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									_ ,  err  =  globalBucketSSEConfigSys . Get ( bucket ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( globalAutoEncryption  ||  err  ==  nil )  &&  ! crypto . SSEC . IsRequested ( r . Header )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										r . Header . Add ( crypto . SSEHeader ,  crypto . SSEAlgorithmAES256 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Require Content-Length to be set in the request
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size  :=  r . ContentLength 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  size  <  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errSizeUnspecified ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Extract incoming metadata if any.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									metadata ,  err  :=  extractMetadata ( ctx ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 07:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ,  guessIsBrowserReq ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 07:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  pReader  * PutObjReader 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  reader  io . Reader  =  r . Body 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									actualSize  :=  size 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hashReader ,  err  :=  hash . NewReader ( reader ,  size ,  "" ,  "" ,  actualSize ,  globalCLIContext . StrictS3Compat ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI . IsCompressionSupported ( )  &&  isCompressible ( r . Header ,  object )  &&  size  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Storing the compression metadata.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 14:08:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										metadata [ ReservedMetadataPrefix + "compression" ]  =  compressionAlgorithmV2 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										metadata [ ReservedMetadataPrefix + "actual-size" ]  =  strconv . FormatInt ( size ,  10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										actualReader ,  err  :=  hash . NewReader ( reader ,  size ,  "" ,  "" ,  actualSize ,  globalCLIContext . StrictS3Compat ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 15:44:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Set compression metrics.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										size  =  - 1  // Since compressed size is un-predictable.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 14:08:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s2c  :=  newS2CompressReader ( actualReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										defer  s2c . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reader  =  s2c 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										hashReader ,  err  =  hash . NewReader ( reader ,  size ,  "" ,  "" ,  actualSize ,  globalCLIContext . StrictS3Compat ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pReader  =  NewPutObjReader ( hashReader ,  nil ,  nil ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// get gateway encryption options
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-09 13:31:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									opts ,  err  =  putOpts ( ctx ,  r ,  bucket ,  object ,  metadata ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-12 17:25:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeErrorResponseHeadersOnly ( w ,  toAPIError ( ctx ,  err ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-06 06:16:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  crypto . IsRequested ( r . Header )  &&  ! HasSuffix ( object ,  SlashSeparator )  {  // handle SSE requests
 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rawReader  :=  hashReader 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 08:01:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  objectEncryptionKey  crypto . ObjectKey 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											reader ,  objectEncryptionKey ,  err  =  EncryptRequest ( hashReader ,  r ,  bucket ,  object ,  metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ,  guessIsBrowserReq ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info  :=  ObjectInfo { Size :  size } 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-09 09:35:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// do not try to verify encrypted content
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hashReader ,  err  =  hash . NewReader ( reader ,  info . EncryptedSize ( ) ,  "" ,  "" ,  size ,  globalCLIContext . StrictS3Compat ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-14 08:07:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeErrorResponse ( ctx ,  w ,  toAPIError ( ctx ,  err ) ,  r . URL ,  guessIsBrowserReq ( r ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 08:01:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pReader  =  NewPutObjReader ( rawReader ,  hashReader ,  & objectEncryptionKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Ensure that metadata does not contain sensitive information
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									crypto . RemoveSensitiveEntries ( metadata ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retentionRequested  :=  objectlock . IsObjectLockRetentionRequested ( r . Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									legalHoldRequested  :=  objectlock . IsObjectLockLegalHoldRequested ( r . Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									putObject  :=  objectAPI . PutObject 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getObjectInfo  :=  objectAPI . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  web . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										putObject  =  web . CacheAPI ( ) . PutObject 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getObjectInfo  =  web . CacheAPI ( ) . GetObjectInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-07 09:10:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  retentionRequested  ||  legalHoldRequested  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// enforce object retention rules
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										retentionMode ,  retentionDate ,  legalHold ,  s3Err  :=  checkPutObjectLockAllowed ( ctx ,  r ,  bucket ,  object ,  getObjectInfo ,  retPerms ,  holdPerms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  s3Err  ==  ErrNone  &&  retentionMode  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											opts . UserDefined [ xhttp . AmzObjectLockMode ]  =  string ( retentionMode ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-26 07:51:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											opts . UserDefined [ xhttp . AmzObjectLockRetainUntilDate ]  =  retentionDate . UTC ( ) . Format ( iso8601TimeFormat ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  s3Err  ==  ErrNone  &&  legalHold . Status  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											opts . UserDefined [ xhttp . AmzObjectLockLegalHold ]  =  string ( legalHold . Status ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  s3Err  !=  ErrNone  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeErrorResponse ( ctx ,  w ,  errorCodes . ToAPIErr ( s3Err ) ,  r . URL ,  guessIsBrowserReq ( r ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-05 22:20:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 00:30:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objInfo ,  err  :=  putObject ( GlobalContext ,  bucket ,  object ,  pReader ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-15 05:35:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  crypto . IsEncrypted ( objInfo . UserDefined )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  crypto . S3 . IsEncrypted ( objInfo . UserDefined ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSEHeader ,  crypto . SSEAlgorithmAES256 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  crypto . SSEC . IsRequested ( r . Header ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSECAlgorithm ,  r . Header . Get ( crypto . SSECAlgorithm ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSECKeyMD5 ,  r . Header . Get ( crypto . SSECKeyMD5 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-29 13:46:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Notify object created event.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-16 04:03:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sendEvent ( eventArgs { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-03 09:40:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										EventName :     event . ObjectCreatedPut , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Object :        objInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 02:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-29 13:46:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Download - file download handler.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  Download ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "WebDownload" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webTokenAuthenticate ( r . URL . Query ( ) . Get ( "token" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  logger . AuditLog ( w ,  r ,  "WebDownload" ,  claims . Map ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
									
										
										
										
											2020-02-12 11:38:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									object ,  err  :=  url . PathUnescape ( vars [ "object" ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 12:57:40 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getRetPerms  :=  ErrAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									legalHoldPerms  :=  ErrAccessDenied 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Check if anonymous (non-owner) has access to download objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           policy . GetObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           policy . GetObjectRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getRetPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Action :           policy . GetObjectLegalHoldAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												legalHoldPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  authErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . GetObjectAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . GetObjectRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											getRetPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Action :           iampolicy . GetObjectLegalHoldAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											BucketName :       bucket , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ObjectName :       object , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											legalHoldPerms  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( bucket ,  false )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getObjectNInfo  :=  objectAPI . GetObjectNInfo 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  web . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getObjectNInfo  =  web . CacheAPI ( ) . GetObjectNInfo 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  opts  ObjectOptions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gr ,  err  :=  getObjectNInfo ( ctx ,  bucket ,  object ,  nil ,  r . Header ,  readLock ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  gr . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objInfo  :=  gr . ObjInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// filter object lock metadata if permission does not permit
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objInfo . UserDefined  =  objectlock . FilterObjectLockMetadata ( objInfo . UserDefined ,  getRetPerms  !=  ErrNone ,  legalHoldPerms  !=  ErrNone ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-15 09:36:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  err  =  DecryptObjectInfo ( & objInfo ,  r . Header ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:56:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set encryption response headers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI . IsEncryptionSupported ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  crypto . IsEncrypted ( objInfo . UserDefined )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  crypto . S3 . IsEncrypted ( objInfo . UserDefined ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSEHeader ,  crypto . SSEAlgorithmAES256 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  crypto . SSEC . IsEncrypted ( objInfo . UserDefined ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSECAlgorithm ,  r . Header . Get ( crypto . SSECAlgorithm ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												w . Header ( ) . Set ( crypto . SSECKeyMD5 ,  r . Header . Get ( crypto . SSECKeyMD5 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-21 10:22:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 15:44:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-06-11 00:22:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Set Parts Count Header
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  opts . PartNumber  >  0  &&  len ( objInfo . Parts )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										setPartsCountHeaders ( w ,  objInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  setObjectHeaders ( w ,  objInfo ,  nil ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Add content disposition.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . Header ( ) . Set ( xhttp . ContentDisposition ,  fmt . Sprintf ( "attachment; filename=\"%s\"" ,  path . Base ( objInfo . Name ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									setHeadGetRespHeaders ( w ,  r . URL . Query ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									httpWriter  :=  ioutil . WriteOnClose ( w ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Write object content to response body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  _ ,  err  =  io . Copy ( httpWriter ,  gr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! httpWriter . HasWritten ( )  {  // write error response only if no data or headers has been written to client yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												fs: Break fs package to top-level and introduce ObjectAPI interface.
ObjectAPI interface brings in changes needed for XL ObjectAPI layer.
The new interface for any ObjectAPI layer is as below
```
// ObjectAPI interface.
type ObjectAPI interface {
        // Bucket resource API.
        DeleteBucket(bucket string) *probe.Error
        ListBuckets() ([]BucketInfo, *probe.Error)
        MakeBucket(bucket string) *probe.Error
        GetBucketInfo(bucket string) (BucketInfo, *probe.Error)
        // Bucket query API.
        ListObjects(bucket, prefix, marker, delimiter string, maxKeys int) (ListObjectsResult, *probe.Error)
        ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error)
        // Object resource API.
        GetObject(bucket, object string, startOffset int64) (io.ReadCloser, *probe.Error)
        GetObjectInfo(bucket, object string) (ObjectInfo, *probe.Error)
        PutObject(bucket string, object string, size int64, data io.Reader, metadata map[string]string) (ObjectInfo, *probe.Error)
        DeleteObject(bucket, object string) *probe.Error
        // Object query API.
        NewMultipartUpload(bucket, object string) (string, *probe.Error)
        PutObjectPart(bucket, object, uploadID string, partID int, size int64, data io.Reader, md5Hex string) (string, *probe.Error)
        ListObjectParts(bucket, object string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error)
        CompleteMultipartUpload(bucket string, object string, uploadID string, parts []CompletePart) (ObjectInfo, *probe.Error)
        AbortMultipartUpload(bucket, object, uploadID string) *probe.Error
}
```
											 
										 
										
											2016-03-31 07:15:28 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  httpWriter . Close ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! httpWriter . HasWritten ( )  {  // write error response only if no data or headers has been written to client yet
 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-06 02:20:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Notify object accessed via a GET request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sendEvent ( eventArgs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										EventName :     event . ObjectAccessedGet , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :    bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Object :        objInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-26 02:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Host :          handlers . GetSourceIP ( r ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-06 02:20:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// DownloadZipArgs - Argument for downloading a bunch of files as a zip file.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// JSON will look like:
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// '{"bucketname":"testbucket","prefix":"john/pics/","objects":["hawaii/","maldives/","sanjose.jpg"]}'
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  DownloadZipArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Objects     [ ] string  ` json:"objects" `     // can be files or sub-directories
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix      string    ` json:"prefix" `      // current directory in the browser-ui
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string    ` json:"bucketname" `  // bucket name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Takes a list of objects and creates a zip file that sent as the response body.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  DownloadZip ( w  http . ResponseWriter ,  r  * http . Request )  {  
						 
					
						
							
								
									
										
										
										
											2019-03-26 02:45:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									host  :=  handlers . GetSourceIP ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-06 02:20:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webTokenAuthenticate ( r . URL . Query ( ) . Get ( "token" ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newContext ( r ,  w ,  "WebDownloadZip" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  logger . AuditLog ( w ,  r ,  "WebDownloadZip" ,  claims . Map ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-13 03:25:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Auth is done after reading the body to accommodate for anonymous requests
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// when bucket policy is enabled.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  args  DownloadZipArgs 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tenKB  :=  10  *  1024  // To limit r.Body to take care of misbehaving anonymous client.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									decodeErr  :=  json . NewDecoder ( io . LimitReader ( r . Body ,  int64 ( tenKB ) ) ) . Decode ( & args ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  decodeErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  decodeErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  getRetPerms  [ ] APIErrorCode 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  legalHoldPerms  [ ] APIErrorCode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  authErr  ==  errNoAuthToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Check if anonymous (non-owner) has access to download objects.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . GetObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 23:59:59 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												retentionPerm  :=  ErrAccessDenied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . GetObjectRetentionAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													retentionPerm  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getRetPerms  =  append ( getRetPerms ,  retentionPerm ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												legalHoldPerm  :=  ErrAccessDenied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  globalPolicySys . IsAllowed ( policy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													Action :           policy . GetObjectLegalHoldAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ConditionValues :  getConditionValues ( r ,  "" ,  "" ,  nil ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													IsOwner :          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													legalHoldPerm  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												legalHoldPerms  =  append ( legalHoldPerms ,  legalHoldPerm ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writeWebErrorResponse ( w ,  authErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  _ ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-14 12:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . GetObjectAction , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											retentionPerm  :=  ErrAccessDenied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . GetObjectRetentionAction , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												retentionPerm  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											getRetPerms  =  append ( getRetPerms ,  retentionPerm ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											legalHoldPerm  :=  ErrAccessDenied 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Action :           iampolicy . GetObjectLegalHoldAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ObjectName :       pathJoin ( args . Prefix ,  object ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												legalHoldPerm  =  ErrNone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											legalHoldPerms  =  append ( legalHoldPerms ,  legalHoldPerm ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									getObjectNInfo  :=  objectAPI . GetObjectNInfo 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  web . CacheAPI ( )  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										getObjectNInfo  =  web . CacheAPI ( ) . GetObjectNInfo 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									archive  :=  zip . NewWriter ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  archive . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-10 05:00:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  i ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Writes compressed object file to the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										zipit  :=  func ( objectName  string )  error  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  opts  ObjectOptions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gr ,  err  :=  getObjectNInfo ( ctx ,  args . BucketName ,  objectName ,  nil ,  r . Header ,  readLock ,  opts ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											defer  gr . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info  :=  gr . ObjInfo 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-21 05:18:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// filter object lock metadata if permission does not permit
 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-17 07:41:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											info . UserDefined  =  objectlock . FilterObjectLockMetadata ( info . UserDefined ,  getRetPerms [ i ]  !=  ErrNone ,  legalHoldPerms [ i ]  !=  ErrNone ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-25 02:19:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// For reporting, set the file size to the uncompressed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info . Size ,  err  =  info . GetActualSize ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											header  :=  & zip . FileHeader { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 04:43:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Name :      strings . TrimPrefix ( objectName ,  args . Prefix ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Method :    zip . Deflate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Flags :     1  <<  11 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Modified :  info . ModTime , 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 14:08:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  hasStringSuffixInSlice ( info . Name ,  standardExcludeCompressExtensions )  ||  hasPattern ( standardExcludeCompressContentTypes ,  info . ContentType )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// We strictly disable compression for standard extensions/content-types.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												header . Method  =  zip . Store 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-09-26 14:08:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											writer ,  err  :=  archive . CreateHeader ( header ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errUnexpected ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											httpWriter  :=  ioutil . WriteOnClose ( writer ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Write object content to response body
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  err  =  io . Copy ( httpWriter ,  gr ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-09-28 11:36:17 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												httpWriter . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ! httpWriter . HasWritten ( )  {  // write error response only if no data or headers has been written to client yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-10 08:09:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  =  httpWriter . Close ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ! httpWriter . HasWritten ( )  {  // write error response only if no data has been written to client yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-06 02:20:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Notify object accessed via a GET request.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											sendEvent ( eventArgs { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												EventName :     event . ObjectAccessedGet , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												BucketName :    args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Object :        info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ReqParams :     extractReqParams ( r ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												RespElements :  extractRespElements ( w ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UserAgent :     r . UserAgent ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Host :          host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-18 03:52:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-12-06 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! HasSuffix ( object ,  SlashSeparator )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											// If not a directory, compress the file and write it to response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  :=  zipit ( pathJoin ( args . Prefix ,  object ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-04-07 04:44:16 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objInfoCh  :=  make ( chan  ObjectInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Walk through all objects
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  :=  objectAPI . Walk ( ctx ,  args . BucketName ,  pathJoin ( args . Prefix ,  object ) ,  objInfoCh ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  obj  :=  range  objInfoCh  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  :=  zipit ( obj . Name ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetBucketPolicyArgs - get bucket policy args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  GetBucketPolicyArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix      string  ` json:"prefix" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetBucketPolicyRep - get bucket policy reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  GetBucketPolicyRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									UIVersion  string                      ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy     miniogopolicy . BucketPolicy  ` json:"policy" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 10:45:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetBucketPolicy - get bucket policy for the requested prefix.
  
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  GetBucketPolicy ( r  * http . Request ,  args  * GetBucketPolicyArgs ,  reply  * GetBucketPolicyRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebGetBucketPolicy" ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-28 03:38:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . GetBucketPolicyAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  policyInfo  =  & miniogopolicy . BucketAccessPolicy { Version :  "2012-10-17" } 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 10:45:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										client ,  rerr  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rerr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  rerr ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyStr ,  err  :=  client . GetBucketPolicy ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  rerr ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketPolicy ,  err  :=  policy . ParseConfig ( strings . NewReader ( policyStr ) ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  rerr ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyInfo ,  err  =  PolicyToBucketAccessPolicy ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This should not happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketPolicy ,  err  :=  globalPolicySys . Get ( args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  err . ( BucketPolicyNotFound ) ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										policyInfo ,  err  =  PolicyToBucketAccessPolicy ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This should not happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . Policy  =  miniogopolicy . GetPolicy ( policyInfo . Statements ,  args . BucketName ,  args . Prefix ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListAllBucketPoliciesArgs - get all bucket policies.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ListAllBucketPoliciesArgs  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-17 03:21:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// BucketAccessPolicy - Collection of canned bucket policy at a given prefix.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  BucketAccessPolicy  struct  {  
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Bucket  string                      ` json:"bucket" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix  string                      ` json:"prefix" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy  miniogopolicy . BucketPolicy  ` json:"policy" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ListAllBucketPoliciesRep - get all bucket policy reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  ListAllBucketPoliciesRep  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string                ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-17 03:21:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Policies   [ ] BucketAccessPolicy  ` json:"policies" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// ListAllBucketPolicies - get all bucket policy.
  
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  ListAllBucketPolicies ( r  * http . Request ,  args  * ListAllBucketPoliciesArgs ,  reply  * ListAllBucketPoliciesRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-07-12 05:37:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebListAllBucketPolicies" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . GetBucketPolicyAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-16 03:00:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  policyInfo  =  new ( miniogopolicy . BucketAccessPolicy ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										core ,  rerr  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rerr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  rerr ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  policyStr  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyStr ,  err  =  core . Client . GetBucketPolicy ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  policyStr  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  json . Unmarshal ( [ ] byte ( policyStr ) ,  policyInfo ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketPolicy ,  err  :=  globalPolicySys . Get ( args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  err . ( BucketPolicyNotFound ) ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyInfo ,  err  =  PolicyToBucketAccessPolicy ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  prefix ,  policy  :=  range  miniogopolicy . GetPolicies ( policyInfo . Statements ,  args . BucketName ,  "" )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-22 06:07:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketName ,  objectPrefix  :=  path2BucketObject ( prefix ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-28 11:14:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										objectPrefix  =  strings . TrimSuffix ( objectPrefix ,  "*" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-17 03:21:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reply . Policies  =  append ( reply . Policies ,  BucketAccessPolicy { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-28 11:14:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Bucket :  bucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Prefix :  objectPrefix , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Policy :  policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SetBucketPolicyWebArgs - set bucket policy args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SetBucketPolicyWebArgs  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix      string  ` json:"prefix" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy      string  ` json:"policy" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetBucketPolicy - set bucket policy.
  
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  SetBucketPolicy ( r  * http . Request ,  args  * SetBucketPolicyWebArgs ,  reply  * WebGenericRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebSetBucketPolicy" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 07:35:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-05 23:11:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 07:35:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// For authenticated users apply IAM policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Action :           iampolicy . PutBucketPolicyAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-09 23:17:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errAccessDenied ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 07:35:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									policyType  :=  miniogopolicy . BucketPolicy ( args . Policy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! policyType . IsValidBucketPolicy ( )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Message :  "Invalid policy type "  +  args . Policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  isRemoteCallRequired ( ctx ,  args . BucketName ,  objectAPI )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sr ,  err  :=  globalDNSConfig . Get ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  dns . ErrNoEntriesFound  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  BucketNotFound { 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													Bucket :  args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										core ,  rerr  :=  getRemoteInstanceClient ( r ,  getHostFromSrv ( sr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  rerr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  rerr ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  policyStr  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Use the abstracted API instead of core, such that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// NoSuchBucketPolicy errors are automatically handled.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyStr ,  err  =  core . Client . GetBucketPolicy ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  policyInfo  =  & miniogopolicy . BucketAccessPolicy { Version :  "2012-10-17" } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  policyStr  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  json . Unmarshal ( [ ] byte ( policyStr ) ,  policyInfo ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										policyInfo . Statements  =  miniogopolicy . SetPolicy ( policyInfo . Statements ,  policyType ,  args . BucketName ,  args . Prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( policyInfo . Statements )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  core . SetBucketPolicy ( args . BucketName ,  "" ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketPolicy ,  err  :=  BucketAccessPolicyToPolicy ( policyInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This should not happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										policyData ,  err  :=  json . Marshal ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 18:11:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  core . SetBucketPolicy ( args . BucketName ,  string ( policyData ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-28 07:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										bucketPolicy ,  err  :=  globalPolicySys . Get ( args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  _ ,  ok  :=  err . ( BucketPolicyNotFound ) ;  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyInfo ,  err  :=  PolicyToBucketAccessPolicy ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This should not happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-28 11:14:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										policyInfo . Statements  =  miniogopolicy . SetPolicy ( policyInfo . Statements ,  policyType ,  args . BucketName ,  args . Prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( policyInfo . Statements )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  =  globalBucketMetadataSys . Update ( args . BucketName ,  bucketPolicyConfig ,  nil ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										bucketPolicy ,  err  =  BucketAccessPolicyToPolicy ( policyInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// This should not happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-10 07:19:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										configData ,  err  :=  json . Marshal ( bucketPolicy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-20 04:53:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Parse validate and save bucket policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  =  globalBucketMetadataSys . Update ( args . BucketName ,  bucketPolicyConfig ,  configData ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-12-19 21:13:47 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-25 06:53:30 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PresignedGetArgs - presigned-get API args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  PresignedGetArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Host header required for signed headers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									HostName  string  ` json:"host" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Bucket name of the object to be presigned.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucket" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Object name to be presigned.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ObjectName  string  ` json:"object" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Expiry in seconds.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Expiry  int64  ` json:"expiry" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PresignedGetRep - presigned-get URL reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  PresignedGetRep  struct  {  
						 
					
						
							
								
									
										
										
										
											2016-10-24 03:32:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Presigned URL of the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									URL  string  ` json:"url" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// PresignedGET - returns presigned-Get url.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  PresignedGet ( r  * http . Request ,  args  * PresignedGetArgs ,  reply  * PresignedGetRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebPresignedGet" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									claims ,  owner ,  authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  creds  auth . Credentials 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! owner  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  ok  bool 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-31 10:59:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creds ,  ok  =  globalIAMSys . GetUser ( claims . AccessKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( ctx ,  errInvalidAccessKeyID ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										creds  =  globalActiveCred 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									region  :=  globalServerRegion 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  args . BucketName  ==  ""  ||  args . ObjectName  ==  ""  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Message :  "Bucket and Object are mandatory arguments." , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if bucket is a reserved bucket name or invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName ,  false )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-04-04 14:10:37 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-05-18 14:38:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Check if the user indeed has GetObject access,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// if not we do not need to generate presigned URLs
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! globalIAMSys . IsAllowed ( iampolicy . Args { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AccountName :      claims . AccessKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Action :           iampolicy . GetObjectAction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										BucketName :       args . BucketName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ConditionValues :  getConditionValues ( r ,  "" ,  claims . AccessKey ,  claims . Map ( ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										IsOwner :          owner , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ObjectName :       args . ObjectName , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Claims :           claims . Map ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errPresignedNotAllowed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . URL  =  presignedGet ( args . HostName ,  args . BucketName ,  args . ObjectName ,  args . Expiry ,  creds ,  region ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns presigned url for GET method.
  
						 
					
						
							
								
									
										
										
										
											2018-10-18 07:23:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  presignedGet ( host ,  bucket ,  object  string ,  expiry  int64 ,  creds  auth . Credentials ,  region  string )  string  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									accessKey  :=  creds . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									secretKey  :=  creds . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									date  :=  UTCNow ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-11 13:57:15 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									dateStr  :=  date . Format ( iso8601Format ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									credential  :=  fmt . Sprintf ( "%s/%s" ,  accessKey ,  getScope ( date ,  region ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  expiryStr  =  "604800"  // Default set to be expire in 7days.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  expiry  <  604800  &&  expiry  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expiryStr  =  strconv . FormatInt ( expiry ,  10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-06 01:48:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query  :=  url . Values { } 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									query . Set ( xhttp . AmzAlgorithm ,  signV4Algorithm ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( xhttp . AmzCredential ,  credential ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( xhttp . AmzDate ,  dateStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( xhttp . AmzExpires ,  expiryStr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									query . Set ( xhttp . AmzSignedHeaders ,  "host" ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-06 01:48:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									queryStr  :=  s3utils . QueryEncode ( query ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-08-07 03:08:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									path  :=  SlashSeparator  +  path . Join ( bucket ,  object ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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" ,  host ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									canonicalRequest  :=  getCanonicalRequest ( extractedSignedHeaders ,  unsignedPayload ,  queryStr ,  path ,  http . MethodGet ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 05:09:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  getStringToSign ( canonicalRequest ,  date ,  getScope ( date ,  region ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-28 09:46:55 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signingKey  :=  getSigningKey ( secretKey ,  date ,  region ,  serviceS3 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signature  :=  getSignature ( signingKey ,  stringToSign ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Construct the final presigned URL.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  creds . SessionToken  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  host  +  s3utils . EncodePath ( path )  +  "?"  +  queryStr  +  "&"  +  xhttp . AmzSignature  +  "="  +  signature  +  "&"  +  xhttp . AmzSecurityToken  +  "="  +  creds . SessionToken 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-03 13:34:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  host  +  s3utils . EncodePath ( path )  +  "?"  +  queryStr  +  "&"  +  xhttp . AmzSignature  +  "="  +  signature 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// DiscoveryDocResp - OpenID discovery document reply.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  DiscoveryDocResp  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									DiscoveryDoc  openid . DiscoveryDoc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion     string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 13:37:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ClientID      string  ` json:"clientId" ` 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetDiscoveryDoc - returns parsed value of OpenID discovery document
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  GetDiscoveryDoc ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * DiscoveryDocResp )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalOpenIDConfig . DiscoveryDoc . AuthEndpoint  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . DiscoveryDoc  =  globalOpenIDConfig . DiscoveryDoc 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-30 13:37:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reply . ClientID  =  globalOpenIDConfig . ClientID 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// LoginSTSArgs - login arguments.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  LoginSTSArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Token  string  ` json:"token" form:"token" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// LoginSTS - STS user login handler.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  LoginSTS ( r  * http . Request ,  args  * LoginSTSArgs ,  reply  * LoginRep )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctx  :=  newWebContext ( r ,  args ,  "WebLoginSTS" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v  :=  url . Values { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v . Set ( "Action" ,  webIdentity ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v . Set ( "WebIdentityToken" ,  args . Token ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v . Set ( "Version" ,  stsAPIVersion ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									scheme  :=  "http" 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-02 14:53:01 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  sourceScheme  :=  handlers . GetSourceScheme ( r ) ;  sourceScheme  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										scheme  =  sourceScheme 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  globalIsSSL  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										scheme  =  "https" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u  :=  & url . URL { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Scheme :  scheme , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Host :    r . Host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									u . RawQuery  =  v . Encode ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									req ,  err  :=  http . NewRequest ( http . MethodPost ,  u . String ( ) ,  nil ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									clnt  :=  & http . Client { 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-22 13:10:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Transport :  NewGatewayHTTPTransport ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-18 02:20:56 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  clnt . CloseIdleConnections ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									resp ,  err  :=  clnt . Do ( req ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  xhttp . DrainBody ( resp . Body ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-03-22 13:10:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-23 13:59:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  resp . StatusCode  !=  http . StatusOK  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  errors . New ( resp . Status ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									a  :=  AssumeRoleWithWebIdentityResponse { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  xml . NewDecoder ( resp . Body ) . Decode ( & a ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( ctx ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . Token  =  a . Result . Credentials . SessionToken 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// toJSONError converts regular errors into more user friendly
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and consumable error message for the browser UI.
  
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  toJSONError ( ctx  context . Context ,  err  error ,  params  ... string )  ( jerr  * json2 . Error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiErr  :=  toWebAPIError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									jerr  =  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Message :  apiErr . Description , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  apiErr . Code  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Reserved bucket name provided.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "AllAccessDisabled" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( params )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jerr  =  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Message :  fmt . Sprintf ( "All access to this bucket %s has been disabled." ,  params [ 0 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Bucket name invalid with custom error message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "InvalidBucketName" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( params )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jerr  =  & json2 . Error { 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-19 22:30:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												Message :  fmt . Sprintf ( "Bucket Name %s is invalid. Lowercase letters, period, hyphen, numerals are the only allowed characters and should be minimum 3 characters in length." ,  params [ 0 ] ) , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Bucket not found custom error message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "NoSuchBucket" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( params )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jerr  =  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Message :  fmt . Sprintf ( "The specified bucket %s does not exist." ,  params [ 0 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Object not found custom error message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  "NoSuchKey" : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( params )  >  1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jerr  =  & json2 . Error { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Message :  fmt . Sprintf ( "The specified key %s does not exist" ,  params [ 1 ] ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Add more custom error messages here with more context.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  jerr 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// toWebAPIError - convert into error into APIError.
  
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  toWebAPIError ( ctx  context . Context ,  err  error )  APIError  {  
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  err  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 08:15:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errNoAuthToken : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "WebTokenMissing" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errServerNotInitialized : 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "XMinioServerNotInitialized" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusServiceUnavailable , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-07 08:15:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errAuthentication ,  auth . ErrInvalidAccessKeyLength , 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-07 12:31:44 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										auth . ErrInvalidSecretKeyLength ,  errInvalidAccessKeyID ,  errAccessDenied ,  errLockedObject : 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 17:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "AccessDenied" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errSizeUnspecified : 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "InvalidRequest" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errChangeCredNotAllowed : 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "MethodNotAllowed" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusMethodNotAllowed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errInvalidBucketName : 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-02 03:16:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Code :            "InvalidBucketName" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errInvalidArgument : 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "InvalidArgument" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errEncryptedObject : 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:56:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrSSEEncryptedObject ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errInvalidEncryptionParameters : 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:56:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrInvalidEncryptionParameters ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errObjectTampered : 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-24 22:56:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrObjectTampered ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-18 22:46:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  errMethodNotAllowed : 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-07 09:10:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrMethodNotAllowed ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-07 09:10:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Convert error type to api error code.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  err . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  StorageFull : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrStorageFull ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  BucketNotFound : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrNoSuchBucket ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-08-22 04:01:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  BucketNotEmpty : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  getAPIError ( ErrBucketNotEmpty ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-24 09:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  BucketExists : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrBucketAlreadyOwnedByYou ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  BucketNameInvalid : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  hash . BadDigest : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrBadDigest ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  IncompleteBody : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrIncompleteBody ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ObjectExistsAsDirectory : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrObjectExistsAsDirectory ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ObjectNotFound : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrNoSuchKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ObjectNameInvalid : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrNoSuchKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  InsufficientWriteQuorum : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrWriteQuorum ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  InsufficientReadQuorum : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrReadQuorum ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NotImplemented : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "NotImplemented" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     "Functionality not implemented" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Log unexpected and unhandled errors.
 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									logger . LogIf ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-04 03:28:52 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  toAPIError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// writeWebErrorResponse - set HTTP status code and write error description to the body.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  writeWebErrorResponse ( w  http . ResponseWriter ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reqInfo  :=  & logger . ReqInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DeploymentID :  globalDeploymentID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2020-04-10 00:30:02 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ctx  :=  logger . SetReqInfo ( GlobalContext ,  reqInfo ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-04 06:40:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									apiErr  :=  toWebAPIError ( ctx ,  err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									w . WriteHeader ( apiErr . HTTPStatusCode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . Write ( [ ] byte ( apiErr . Description ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}