2016-01-26 09:29:20 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2017-03-19 02:28:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Minio  Cloud  Storage ,  ( C )  2016 ,  2017  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  (  
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"archive/zip" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"encoding/json" 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"io/ioutil" 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"net/http" 
							 
						 
					
						
							
								
									
										
										
										
											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-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/dustin/go-humanize" 
							 
						 
					
						
							
								
									
										
										
										
											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" 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio-go/pkg/policy" 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-24 10:07:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/browser" 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/auth" 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/hash" 
							 
						 
					
						
							
								
									
										
										
										
											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 { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  {  
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-04 14:46:45 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									host ,  err  :=  os . Hostname ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host  =  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memstats  :=  & runtime . MemStats { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									runtime . ReadMemStats ( memstats ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mem  :=  fmt . Sprintf ( "Used: %s | Allocated: %s | Used-Heap: %s | Allocated-Heap: %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										humanize . Bytes ( memstats . Alloc ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										humanize . Bytes ( memstats . TotalAlloc ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										humanize . Bytes ( memstats . HeapAlloc ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										humanize . Bytes ( memstats . HeapSys ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									platform  :=  fmt . Sprintf ( "Host: %s | OS: %s | Arch: %s" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										host , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . GOOS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runtime . GOARCH ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									goruntime  :=  fmt . Sprintf ( "Version: %s | CPUs: %s" ,  runtime . Version ( ) ,  strconv . Itoa ( 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 ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-09 04:40:22 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									reply . MinioMemory  =  mem 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									StorageInfo  StorageInfo  ` json:"storageInfo" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion    string       ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// StorageInfo - web call to gather storage usage statistics.
  
						 
					
						
							
								
									
										
										
										
											2016-12-23 23:12:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  StorageInfo ( r  * http . Request ,  args  * AuthRPCArgs ,  reply  * StorageInfoRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . StorageInfo  =  objectAPI . StorageInfo ( ) 
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  isReservedOrInvalidBucket ( args . BucketName )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( errInvalidBucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-03 19:01:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketLock  :=  globalNSMutex . NewNSLock ( args . BucketName ,  "" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-01 02:29:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  bucketLock . GetLock ( globalObjectTimeout ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( errOperationTimedOut ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  bucketLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  objectAPI . MakeBucketWithLocation ( args . BucketName ,  serverConfig . GetRegion ( ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( 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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( authErr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									buckets ,  err  :=  objectAPI . ListBuckets ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-04-30 05:24:10 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-25 14:26:53 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  _ ,  bucket  :=  range  buckets  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reply . Buckets  =  append ( reply . Buckets ,  WebBucketInfo { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Name :          bucket . Name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											CreationDate :  bucket . Created , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +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  {  
						 
					
						
							
								
									
										
										
										
											2017-02-11 14:54:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Objects      [ ] WebObjectInfo  ` json:"objects" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									NextMarker   string           ` json:"nextmarker" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									IsTruncated  bool             ` json:"istruncated" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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  {  
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prefix  :=  args . Prefix  +  "test"  // To test if GetObject/PutObject with the specified prefix is allowed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readable  :=  isBucketActionAllowed ( "s3:GetObject" ,  args . BucketName ,  prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									writable  :=  isBucketActionAllowed ( "s3:PutObject" ,  args . BucketName ,  prefix ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  authErr  ==  errAuthentication : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( authErr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  authErr  ==  nil : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  readable  &&  writable : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . Writable  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  readable : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  writable : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . Writable  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  errAuthentication 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-11 14:54:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									lo ,  err  :=  objectAPI . ListObjects ( args . BucketName ,  args . Prefix ,  args . Marker ,  slashSeparator ,  1000 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & json2 . Error { Message :  err . Error ( ) } 
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-11 14:54:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . NextMarker  =  lo . NextMarker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . IsTruncated  =  lo . IsTruncated 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-01-24 11:44:32 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
									
										
										
										
											2016-08-01 05:11:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errInvalidArgument ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! hasSuffix ( objectName ,  slashSeparator )  &&  objectName  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  =  deleteObject ( objectAPI ,  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// For directories, list the contents recursively and remove.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										marker  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  lo  ListObjectsInfo 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											lo ,  err  =  objectAPI . ListObjects ( args . BucketName ,  objectName ,  marker ,  "" ,  1000 ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break  next 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											marker  =  lo . NextMarker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  obj  :=  range  lo . Objects  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												err  =  deleteObject ( objectAPI ,  args . BucketName ,  obj . Name ,  r ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break  next 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-01 11:07:28 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! lo . IsTruncated  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( err ,  args . BucketName ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-10 23:42:55 +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-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  {  
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 17:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Make sure to log errors related to browser login,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// for security and auditing reasons.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorIf ( err ,  "Unable to login request from %s" ,  r . RemoteAddr ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( 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  {  
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred  :=  auth . MustGetNewCredentials ( ) 
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccessKey  string  ` json:"accessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SecretKey  string  ` json:"secretKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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  {  
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If creds are set through ENV disallow changing credentials.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  globalIsEnvCreds  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( errChangeCredNotAllowed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									creds ,  err  :=  auth . CreateCredentials ( args . AccessKey ,  args . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-16 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Notify all other Minio peers to update credentials
 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-27 08:51:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									errsMap  :=  updateCredsOnPeers ( creds ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Update local credentials
 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-09 03:14:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prevCred  :=  serverConfig . SetCredential ( creds ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-27 08:51:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Persist updated credentials.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-16 15:16:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  serverConfig . Save ( ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-08-09 03:14:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Save the current creds when failed to update.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										serverConfig . SetCredential ( prevCred ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										errsMap [ globalMinioAddr ]  =  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Log all the peer related error messages, and populate the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// PeerErrMsgs map.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . PeerErrMsgs  =  make ( map [ string ] string ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  svr ,  errVal  :=  range  errsMap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tErr  :=  fmt . Errorf ( "Unable to change credentials on %s: %v" ,  svr ,  errVal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorIf ( tErr ,  "Credentials change could not be propagated successfully!" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										reply . PeerErrMsgs [ svr ]  =  errVal . Error ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-11-08 03:43:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// If we were unable to update locally, we return an error to the user/browser.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  errsMap [ globalMinioAddr ]  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Since the error message may be very long to display
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// on the browser, we tell the user to check the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// server logs.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errors . New ( "unexpected error(s) occurred - please check minio server logs" ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// As we have updated access/secret key, generate new auth token.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									token ,  err  :=  authenticateWeb ( creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										// Did we have peer errors?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  len ( errsMap )  >  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  fmt . Errorf ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"we gave up due to: '%s', but there were more errors. Please check minio server logs" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-18 11:18:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									reply . Token  =  token 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-22 02:15:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetAuthReply - Reply current credentials.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  GetAuthReply  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AccessKey  string  ` json:"accessKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									SecretKey  string  ` json:"secretKey" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string  ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// GetAuth - return accessKey and secretKey credentials.
  
						 
					
						
							
								
									
										
										
										
											2016-04-13 03:45:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  GetAuth ( r  * http . Request ,  args  * WebGenericArgs ,  reply  * GetAuthReply )  error  {  
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									creds  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . AccessKey  =  creds . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . SecretKey  =  creds . SecretKey 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									creds  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									token ,  err  :=  authenticateURL ( creds . AccessKey ,  creds . SecretKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reply . Token  =  token 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 )  {  
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									object  :=  vars [ "object" ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									authErr  :=  webRequestAuthenticate ( r ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  authErr  ==  errAuthentication  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  authErr  !=  nil  &&  ! isBucketActionAllowed ( "s3:PutObject" ,  bucket ,  object )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-07-06 07:56:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									metadata ,  err  :=  extractMetadataFromHeader ( r . Header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										errorIf ( err ,  "found invalid http request header" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeErrorResponse ( w ,  ErrInternalError ,  r . URL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Lock the object.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectLock  :=  globalNSMutex . NewNSLock ( bucket ,  object ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-01 02:29:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectLock . GetLock ( globalObjectTimeout )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errOperationTimedOut ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  objectLock . Unlock ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-28 12:11:15 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-22 13:30:34 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									hashReader ,  err  :=  hash . NewReader ( r . Body ,  size ,  "" ,  "" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objInfo ,  err  :=  objectAPI . PutObject ( bucket ,  object ,  hashReader ,  metadata ) 
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-29 13:46:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Notify object created event.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									eventNotify ( eventData { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-14 05:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										Type :       ObjectCreatedPut , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Bucket :     bucket , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ObjInfo :    objInfo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ReqParams :  extractReqParams ( 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 )  {  
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									vars  :=  mux . Vars ( r ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucket  :=  vars [ "bucket" ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									object  :=  vars [ "object" ] 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									token  :=  r . URL . Query ( ) . Get ( "token" ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 12:57:40 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-12 05:26:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isAuthTokenValid ( token )  &&  ! isBucketActionAllowed ( "s3:GetObject" ,  bucket ,  object )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-04-08 14:44:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Add content disposition.
 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-18 04:26:08 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									w . Header ( ) . Set ( "Content-Disposition" ,  fmt . Sprintf ( "attachment; filename=\"%s\"" ,  path . Base ( object ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-03-31 21:57:29 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Lock the object before reading.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectLock  :=  globalNSMutex . NewNSLock ( bucket ,  object ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-01 02:29:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  objectLock . GetRLock ( globalObjectTimeout )  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errOperationTimedOut ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  objectLock . RUnlock ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-01-27 08:51:51 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  objectAPI . GetObject ( bucket ,  object ,  0 ,  - 1 ,  w ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/// No need to print error, response writer already written to.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
									
										
										
										
											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 )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										writeWebErrorResponse ( w ,  errServerNotInitialized ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-05-11 00:54:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									token  :=  r . URL . Query ( ) . Get ( "token" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! isAuthTokenValid ( token )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  _ ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! isBucketActionAllowed ( "s3:GetObject" ,  args . BucketName ,  pathJoin ( args . Prefix ,  object ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errAuthentication ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-09 15:39:08 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									archive  :=  zip . NewWriter ( w ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  archive . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  object  :=  range  args . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// Writes compressed object file to the response.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										zipit  :=  func ( objectName  string )  error  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											info ,  err  :=  objectAPI . GetObjectInfo ( args . BucketName ,  objectName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											header  :=  & zip . FileHeader { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Name :                strings . TrimPrefix ( objectName ,  args . Prefix ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												Method :              zip . Deflate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UncompressedSize64 :  uint64 ( info . Size ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												UncompressedSize :    uint32 ( info . Size ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											writer ,  err  :=  archive . CreateHeader ( header ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												writeWebErrorResponse ( w ,  errUnexpected ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  objectAPI . GetObject ( args . BucketName ,  objectName ,  0 ,  info . Size ,  writer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-17 06:52:14 +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  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// For directories, list the contents recursively and write the objects as compressed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// date to the response writer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										marker  :=  "" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											lo ,  err  :=  objectAPI . ListObjects ( args . BucketName ,  pathJoin ( args . Prefix ,  object ) ,  marker ,  "" ,  1000 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											marker  =  lo . NextMarker 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  _ ,  obj  :=  range  lo . Objects  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												err  =  zipit ( obj . Name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ! lo . IsTruncated  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									UIVersion  string               ` json:"uiVersion" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy     policy . BucketPolicy  ` json:"policy" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  readBucketAccessPolicy ( objAPI  ObjectLayer ,  bucketName  string )  ( policy . BucketAccessPolicy ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketPolicyReader ,  err  :=  readBucketPolicyJSON ( bucketName ,  objAPI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  _ ,  ok  :=  err . ( BucketPolicyNotFound ) ;  ok  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 13:27:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  policy . BucketAccessPolicy { Version :  "2012-10-17" } ,  nil 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  policy . BucketAccessPolicy { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bucketPolicyBuf ,  err  :=  ioutil . ReadAll ( bucketPolicyReader ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  policy . BucketAccessPolicy { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									policyInfo  :=  policy . BucketAccessPolicy { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  json . Unmarshal ( bucketPolicyBuf ,  & policyInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  policy . BucketAccessPolicy { } ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  policyInfo ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  getBucketAccessPolicy ( objAPI  ObjectLayer ,  bucketName  string )  ( policy . BucketAccessPolicy ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// FIXME: remove this code when S3 layer for gateway and server is unified.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-28 06:07:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  layer ,  ok  :=  objAPI . ( GatewayLayer ) ;  ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  layer . GetBucketPolicies ( bucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-28 06:07:46 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  readBucketAccessPolicy ( objAPI ,  bucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +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  {  
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 10:22:27 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 10:45:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  policyInfo ,  err  =  getBucketAccessPolicy ( objectAPI ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 10:45:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  ok  :=  errorCause ( err ) . ( PolicyNotFound ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . Policy  =  policy . 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  {  
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									Prefix  string               ` json:"prefix" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy  policy . BucketPolicy  ` json:"policy" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// GetllBucketPolicy - get all bucket policy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  ListAllBucketPolicies ( r  * http . Request ,  args  * ListAllBucketPoliciesArgs ,  reply  * ListAllBucketPoliciesRep )  error  {  
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									objectAPI  :=  web . ObjectAPI ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  objectAPI  ==  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-20 10:45:13 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  policyInfo ,  err  =  getBucketAccessPolicy ( objectAPI ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										_ ,  ok  :=  errorCause ( err ) . ( PolicyNotFound ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  prefix ,  policy  :=  range  policy . GetPolicies ( policyInfo . Statements ,  args . BucketName )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-03-17 03:21:58 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										reply . Policies  =  append ( reply . Policies ,  BucketAccessPolicy { 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 12:53:19 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Prefix :  prefix , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Policy :  policy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 14:06:45 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// SetBucketPolicyArgs - set bucket policy args.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  SetBucketPolicyArgs  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BucketName  string  ` json:"bucketName" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Prefix      string  ` json:"prefix" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									Policy      string  ` json:"policy" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// SetBucketPolicy - set bucket policy.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  ( web  * webAPIHandlers )  SetBucketPolicy ( r  * http . Request ,  args  * SetBucketPolicyArgs ,  reply  * WebGenericRep )  error  {  
						 
					
						
							
								
									
										
										
										
											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  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errServerNotInitialized ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-03 05:45:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 07:35:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 13:27:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									bucketP  :=  policy . BucketPolicy ( args . Policy ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ! bucketP . 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  policyInfo ,  err  =  getBucketAccessPolicy ( objectAPI ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  _ ,  ok  :=  errorCause ( err ) . ( PolicyNotFound ) ;  ! ok  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										policyInfo  =  policy . BucketAccessPolicy { Version :  "2012-10-17" } 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 13:27:21 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									policyInfo . Statements  =  policy . SetPolicy ( policyInfo . Statements ,  bucketP ,  args . BucketName ,  args . Prefix ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  g  :=  objectAPI . ( type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  GatewayLayer : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  len ( policyInfo . Statements )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  g . DeleteBucketPolicies ( args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-02 00:43:20 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										err  =  g . SetBucketPolicies ( args . BucketName ,  policyInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  toJSONError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 18:11:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  len ( policyInfo . Statements )  ==  0  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-28 07:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  persistAndNotifyBucketPolicyChange ( args . BucketName ,  policyChange { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											true ,  policy . BucketAccessPolicy { } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ,  objectAPI ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-26 18:11:22 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-28 07:14:06 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									data ,  err  :=  json . Marshal ( policyInfo ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( err ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-31 01:04:50 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-11 08:15:12 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									// Parse validate and save bucket policy.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  s3Error  :=  parseAndPersistBucketPolicy ( args . BucketName ,  data ,  objectAPI ) ;  s3Error  !=  ErrNone  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										apiErr  :=  getAPIError ( s3Error ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-24 09:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  err  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  apiErr . Code  ==  "XMinioPolicyNesting"  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  PolicyNesting { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											err  =  errors . New ( apiErr . Description ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  toJSONError ( err ,  args . BucketName ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 13:27:21 +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  {  
						 
					
						
							
								
									
										
										
										
											2016-12-28 00:28:10 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ! isHTTPRequestValid ( r )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  toJSONError ( errAuthentication ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-23 09:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . UIVersion  =  browser . UIVersion 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									reply . URL  =  presignedGet ( args . HostName ,  args . BucketName ,  args . ObjectName ,  args . Expiry ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns presigned url for GET method.
  
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  presignedGet ( host ,  bucket ,  object  string ,  expiry  int64 )  string  {  
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cred  :=  serverConfig . GetCredential ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									region  :=  serverConfig . GetRegion ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-12-27 02:21:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									accessKey  :=  cred . AccessKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									secretKey  :=  cred . 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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									query  :=  strings . Join ( [ ] string { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"X-Amz-Algorithm="  +  signV4Algorithm , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"X-Amz-Credential="  +  strings . Replace ( credential ,  "/" ,  "%2F" ,  - 1 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										"X-Amz-Date="  +  dateStr , 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"X-Amz-Expires="  +  expiryStr , 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										"X-Amz-SignedHeaders=host" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ,  "&" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									path  :=  "/"  +  path . Join ( bucket ,  object ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									canonicalRequest  :=  getCanonicalRequest ( extractedSignedHeaders ,  unsignedPayload ,  query ,  path ,  "GET" ) 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-07 05:09:09 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									stringToSign  :=  getStringToSign ( canonicalRequest ,  date ,  getScope ( date ,  region ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									signingKey  :=  getSigningKey ( secretKey ,  date ,  region ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									signature  :=  getSignature ( signingKey ,  stringToSign ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Construct the final presigned URL.
 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-26 09:39:14 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  host  +  getURLEncodedName ( path )  +  "?"  +  query  +  "&"  +  "X-Amz-Signature="  +  signature 
							 
						 
					
						
							
								
									
										
										
										
											2016-09-23 16:24:49 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// toJSONError converts regular errors into more user friendly
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// and consumable error message for the browser UI.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  toJSONError ( err  error ,  params  ... string )  ( jerr  * json2 . Error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiErr  :=  toWebAPIError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  toWebAPIError ( err  error )  APIError  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  errorCause ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  errAuthentication  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "AccessDenied" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 17:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  errServerNotInitialized  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-23 03:12:38 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "XMinioServerNotInitialized" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusServiceUnavailable , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  auth . ErrInvalidAccessKeyLength  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 17:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "AccessDenied" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-01 02:54:32 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  auth . ErrInvalidSecretKeyLength  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-01-03 17:33:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "AccessDenied" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  err  ==  errInvalidAccessKeyID  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "AccessDenied" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusForbidden , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-03 02:45:00 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  errSizeUnspecified  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "InvalidRequest" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-02-08 04:51:43 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  errChangeCredNotAllowed  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "MethodNotAllowed" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusMethodNotAllowed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-09-02 03:16:54 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  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 ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-04-27 14:27:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  err  ==  errInvalidArgument  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "InvalidArgument" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     err . Error ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
									
										
										
										
											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 ) 
							 
						 
					
						
							
								
									
										
										
										
											2016-11-24 09:31:11 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  PolicyNesting : 
							 
						 
					
						
							
								
									
										
										
										
											2017-06-08 10:31:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  getAPIError ( ErrPolicyNesting ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  NotImplemented : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Code :            "NotImplemented" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											HTTPStatusCode :  http . StatusBadRequest , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Description :     "Functionality not implemented" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Log unexpected and unhandled errors.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									errorIf ( err ,  errUnexpected . Error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  APIError { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Code :            "InternalError" , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										HTTPStatusCode :  http . StatusInternalServerError , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Description :     err . Error ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											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 )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									apiErr  :=  toWebAPIError ( err ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . WriteHeader ( apiErr . HTTPStatusCode ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									w . Write ( [ ] byte ( apiErr . Description ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}