| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2019-04-10 02:39:42 +08:00
										 |  |  |  * MinIO Cloud Storage, (C) 2019 MinIO, Inc. | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package cmd | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"context" | 
					
						
							|  |  |  | 	"encoding/gob" | 
					
						
							|  |  |  | 	"errors" | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2019-08-19 10:56:32 +08:00
										 |  |  | 	"io" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	"net/url" | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"strings" | 
					
						
							|  |  |  | 	"time" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/gorilla/mux" | 
					
						
							|  |  |  | 	"github.com/minio/minio/cmd/logger" | 
					
						
							| 
									
										
										
										
											2020-02-05 17:42:34 +08:00
										 |  |  | 	bucketsse "github.com/minio/minio/pkg/bucket/encryption" | 
					
						
							| 
									
										
										
										
											2020-01-28 06:12:34 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/bucket/lifecycle" | 
					
						
							|  |  |  | 	objectlock "github.com/minio/minio/pkg/bucket/object/lock" | 
					
						
							|  |  |  | 	"github.com/minio/minio/pkg/bucket/policy" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	"github.com/minio/minio/pkg/event" | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 	trace "github.com/minio/minio/pkg/trace" | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // To abstract a node over network.
 | 
					
						
							|  |  |  | type peerRESTServer struct { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func getServerInfo() (*ServerInfoData, error) { | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objLayer := newObjectLayerWithoutSafeModeFn() | 
					
						
							|  |  |  | 	if objLayer == nil { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		return nil, errServerNotInitialized | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	// Server info data.
 | 
					
						
							|  |  |  | 	return &ServerInfoData{ | 
					
						
							| 
									
										
										
										
											2019-10-23 12:01:14 +08:00
										 |  |  | 		ConnStats: globalConnStats.toServerConnStats(), | 
					
						
							|  |  |  | 		HTTPStats: globalHTTPStats.toServerHTTPStats(), | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		Properties: ServerProperties{ | 
					
						
							| 
									
										
										
										
											2019-12-12 09:56:02 +08:00
										 |  |  | 			Uptime:       UTCNow().Unix() - globalBootTime.Unix(), | 
					
						
							| 
									
										
										
										
											2019-03-26 02:55:28 +08:00
										 |  |  | 			Version:      Version, | 
					
						
							|  |  |  | 			CommitID:     CommitID, | 
					
						
							|  |  |  | 			DeploymentID: globalDeploymentID, | 
					
						
							|  |  |  | 			SQSARN:       globalNotificationSys.GetARNList(), | 
					
						
							| 
									
										
										
										
											2019-10-23 13:59:13 +08:00
										 |  |  | 			Region:       globalServerRegion, | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		}, | 
					
						
							|  |  |  | 	}, nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-19 10:56:32 +08:00
										 |  |  | // NetReadPerfInfoHandler - returns network read performance information.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) NetReadPerfInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	params := mux.Vars(r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sizeStr, found := params[peerRESTNetPerfSize] | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("size is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size, err := strconv.ParseInt(sizeStr, 10, 64) | 
					
						
							|  |  |  | 	if err != nil || size < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	start := time.Now() | 
					
						
							|  |  |  | 	n, err := io.CopyN(ioutil.Discard, r.Body, size) | 
					
						
							|  |  |  | 	end := time.Now() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if n != size { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, fmt.Errorf("short read; expected: %v, got: %v", size, n)) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	addr := r.Host | 
					
						
							|  |  |  | 	if globalIsDistXL { | 
					
						
							|  |  |  | 		addr = GetLocalPeer(globalEndpoints) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-27 02:31:18 +08:00
										 |  |  | 	d := end.Sub(start) | 
					
						
							| 
									
										
										
										
											2019-08-19 10:56:32 +08:00
										 |  |  | 	info := ServerNetReadPerfInfo{ | 
					
						
							| 
									
										
										
										
											2019-09-27 02:31:18 +08:00
										 |  |  | 		Addr:           addr, | 
					
						
							|  |  |  | 		ReadThroughput: uint64(int64(time.Second) * size / int64(d)), | 
					
						
							| 
									
										
										
										
											2019-08-19 10:56:32 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "NetReadPerfInfo") | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CollectNetPerfInfoHandler - returns network performance information collected from other peers.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) CollectNetPerfInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	params := mux.Vars(r) | 
					
						
							|  |  |  | 	sizeStr, found := params[peerRESTNetPerfSize] | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("size is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size, err := strconv.ParseInt(sizeStr, 10, 64) | 
					
						
							|  |  |  | 	if err != nil || size < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	info := globalNotificationSys.NetReadPerfInfo(size) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "CollectNetPerfInfo") | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // GetLocksHandler - returns list of older lock from the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) GetLocksHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "GetLocks") | 
					
						
							| 
									
										
										
										
											2019-11-14 04:17:45 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	var llockers []map[string][]lockRequesterInfo | 
					
						
							|  |  |  | 	for _, llocker := range globalLockServers { | 
					
						
							|  |  |  | 		llockers = append(llockers, llocker.DupLockMap()) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(llockers)) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeletePolicyHandler - deletes a policy on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeletePolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	policyName := vars[peerRESTPolicy] | 
					
						
							|  |  |  | 	if policyName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("policyName is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := globalIAMSys.DeletePolicy(policyName); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadPolicyHandler - reloads a policy on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	policyName := vars[peerRESTPolicy] | 
					
						
							|  |  |  | 	if policyName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("policyName is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := globalIAMSys.LoadPolicy(objAPI, policyName); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | // LoadPolicyMappingHandler - reloads a policy mapping on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadPolicyMappingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-14 04:41:06 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	userOrGroup := vars[peerRESTUserOrGroup] | 
					
						
							|  |  |  | 	if userOrGroup == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("user-or-group is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	_, isGroup := vars[peerRESTIsGroup] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := globalIAMSys.LoadPolicyMapping(objAPI, userOrGroup, isGroup); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | // DeleteUserHandler - deletes a user on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeleteUserHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("username is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := globalIAMSys.DeleteUser(accessKey); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadUserHandler - reloads a user on the server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadUserHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-07 08:46:22 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	accessKey := vars[peerRESTUser] | 
					
						
							|  |  |  | 	if accessKey == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("username is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	temp, err := strconv.ParseBool(vars[peerRESTUserTemp]) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err = globalIAMSys.LoadUser(objAPI, accessKey, temp); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // LoadUsersHandler - reloads all users and canned policies.
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | func (s *peerRESTServer) LoadUsersHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							|  |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-09 06:10:04 +08:00
										 |  |  | 	err := globalIAMSys.Load() | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | // LoadGroupHandler - reloads group along with members list.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) LoadGroupHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 12:46:57 +08:00
										 |  |  | 	if globalIAMSys == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-03 05:25:00 +08:00
										 |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	group := vars[peerRESTGroup] | 
					
						
							|  |  |  | 	err := globalIAMSys.LoadGroup(objAPI, group) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // StartProfilingHandler - Issues the start profiling command.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) StartProfilingHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	profiles := strings.Split(vars[peerRESTProfiler], ",") | 
					
						
							|  |  |  | 	if len(profiles) == 0 { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("profiler name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	globalProfilerMu.Lock() | 
					
						
							|  |  |  | 	defer globalProfilerMu.Unlock() | 
					
						
							|  |  |  | 	if globalProfiler == nil { | 
					
						
							|  |  |  | 		globalProfiler = make(map[string]minioProfiler, 10) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	// Stop profiler of all types if already running
 | 
					
						
							|  |  |  | 	for k, v := range globalProfiler { | 
					
						
							|  |  |  | 		for _, p := range profiles { | 
					
						
							|  |  |  | 			if p == k { | 
					
						
							|  |  |  | 				v.Stop() | 
					
						
							|  |  |  | 				delete(globalProfiler, k) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	for _, profiler := range profiles { | 
					
						
							|  |  |  | 		prof, err := startProfiler(profiler) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		globalProfiler[profiler] = prof | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | // DownloadProfilingDataHandler - returns profiled data.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DownloadProfilingDataHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "DownloadProfiling") | 
					
						
							|  |  |  | 	profileData, err := getProfileData() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(profileData)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // CPULoadInfoHandler - returns CPU Load info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) CPULoadInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "CPULoadInfo") | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	info := getLocalCPULoad(globalEndpoints, r) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-03 22:48:38 +08:00
										 |  |  | // CPUInfoHandler - returns CPU Hardware info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) CPUInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "CPUInfo") | 
					
						
							|  |  |  | 	info := getLocalCPUInfo(globalEndpoints, r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-17 19:09:50 +08:00
										 |  |  | // NetworkInfoHandler - returns Network Hardware info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) NetworkInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "NetworkInfo") | 
					
						
							|  |  |  | 	info := getLocalNetworkInfo(globalEndpoints, r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-12 06:27:03 +08:00
										 |  |  | // ServerInfoHandler - returns Server Info
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ServerInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "ServerInfo") | 
					
						
							|  |  |  | 	info := getLocalServerProperty(globalEndpoints, r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | // DrivePerfInfoHandler - returns Drive Performance info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DrivePerfInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-13 05:52:30 +08:00
										 |  |  | 	params := mux.Vars(r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	sizeStr, found := params[peerRESTDrivePerfSize] | 
					
						
							|  |  |  | 	if !found { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("size is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	size, err := strconv.ParseInt(sizeStr, 10, 64) | 
					
						
							|  |  |  | 	if err != nil || size < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	ctx := newContext(r, w, "DrivePerfInfo") | 
					
						
							| 
									
										
										
										
											2019-09-13 05:52:30 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	info := getLocalDrivesPerf(globalEndpoints, size, r) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // MemUsageInfoHandler - returns Memory Usage info.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) MemUsageInfoHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "MemUsageInfo") | 
					
						
							| 
									
										
										
										
											2019-09-13 02:06:12 +08:00
										 |  |  | 	info := getLocalMemUsage(globalEndpoints, r) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(info)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // DeleteBucketHandler - Delete notification and policies related to the bucket.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalNotificationSys.RemoveNotification(bucketName) | 
					
						
							|  |  |  | 	globalPolicySys.Remove(bucketName) | 
					
						
							| 
									
										
										
										
											2019-11-22 05:18:32 +08:00
										 |  |  | 	globalBucketObjectLockConfig.Remove(bucketName) | 
					
						
							|  |  |  | 	globalLifecycleSys.Remove(bucketName) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // ReloadFormatHandler - Reload Format.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ReloadFormatHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	dryRunString := vars[peerRESTDryRun] | 
					
						
							|  |  |  | 	if dryRunString == "" { | 
					
						
							| 
									
										
										
										
											2020-01-10 18:35:06 +08:00
										 |  |  | 		s.writeErrorResponse(w, errors.New("dry-run parameter is missing")) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var dryRun bool | 
					
						
							|  |  |  | 	switch strings.ToLower(dryRunString) { | 
					
						
							|  |  |  | 	case "true": | 
					
						
							|  |  |  | 		dryRun = true | 
					
						
							|  |  |  | 	case "false": | 
					
						
							|  |  |  | 		dryRun = false | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-10 01:27:23 +08:00
										 |  |  | 	objAPI := newObjectLayerWithoutSafeModeFn() | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	if objAPI == nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errServerNotInitialized) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2020-01-10 18:35:06 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	err := objAPI.ReloadFormat(context.Background(), dryRun) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // RemoveBucketPolicyHandler - Remove bucket policy.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) RemoveBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalPolicySys.Remove(bucketName) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetBucketPolicyHandler - Set bucket policy.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SetBucketPolicyHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var policyData policy.Policy | 
					
						
							|  |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&policyData) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	globalPolicySys.Set(bucketName, policyData) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-20 04:20:33 +08:00
										 |  |  | // RemoveBucketLifecycleHandler - Remove bucket lifecycle.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) RemoveBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalLifecycleSys.Remove(bucketName) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetBucketLifecycleHandler - Set bucket lifecycle.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SetBucketLifecycleHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var lifecycleData lifecycle.Lifecycle | 
					
						
							|  |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&lifecycleData) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	globalLifecycleSys.Set(bucketName, lifecycleData) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-02-05 17:42:34 +08:00
										 |  |  | // RemoveBucketSSEConfigHandler - Remove bucket encryption.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) RemoveBucketSSEConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalBucketSSEConfigSys.Remove(bucketName) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SetBucketSSEConfigHandler - Set bucket encryption.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SetBucketSSEConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var encConfig bucketsse.BucketSSEConfig | 
					
						
							|  |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&encConfig) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalBucketSSEConfigSys.Set(bucketName, encConfig) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | type remoteTargetExistsResp struct { | 
					
						
							|  |  |  | 	Exists bool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TargetExistsHandler - Check if Target exists.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) TargetExistsHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "TargetExists") | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var targetID event.TargetID | 
					
						
							|  |  |  | 	if r.ContentLength <= 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&targetID) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var targetExists remoteTargetExistsResp | 
					
						
							|  |  |  | 	targetExists.Exists = globalNotificationSys.RemoteTargetExist(bucketName, targetID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(&targetExists)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sendEventRequest struct { | 
					
						
							|  |  |  | 	Event    event.Event | 
					
						
							|  |  |  | 	TargetID event.TargetID | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type sendEventResp struct { | 
					
						
							|  |  |  | 	Success bool | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SendEventHandler - Send Event.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SendEventHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "SendEvent") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	var eventReq sendEventRequest | 
					
						
							|  |  |  | 	if r.ContentLength <= 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&eventReq) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var eventResp sendEventResp | 
					
						
							|  |  |  | 	eventResp.Success = true | 
					
						
							|  |  |  | 	errs := globalNotificationSys.send(bucketName, eventReq.Event, eventReq.TargetID) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for i := range errs { | 
					
						
							|  |  |  | 		reqInfo := (&logger.ReqInfo{}).AppendTags("Event", eventReq.Event.EventName.String()) | 
					
						
							|  |  |  | 		reqInfo.AppendTags("targetName", eventReq.TargetID.Name) | 
					
						
							|  |  |  | 		ctx := logger.SetReqInfo(context.Background(), reqInfo) | 
					
						
							|  |  |  | 		logger.LogIf(ctx, errs[i].Err) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		eventResp.Success = false | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errs[i].Err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(&eventResp)) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // PutBucketNotificationHandler - Set bucket policy.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) PutBucketNotificationHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var rulesMap event.RulesMap | 
					
						
							|  |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&rulesMap) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalNotificationSys.AddRulesMap(bucketName, rulesMap) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-22 05:18:32 +08:00
										 |  |  | // RemoveBucketObjectLockConfigHandler - handles DELETE bucket object lock configuration.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) RemoveBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	globalBucketObjectLockConfig.Remove(bucketName) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-13 06:50:18 +08:00
										 |  |  | // PutBucketObjectLockConfigHandler - handles PUT bucket object lock configuration.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) PutBucketObjectLockConfigHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	bucketName := vars[peerRESTBucket] | 
					
						
							|  |  |  | 	if bucketName == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Bucket name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-17 07:41:56 +08:00
										 |  |  | 	var retention objectlock.Retention | 
					
						
							| 
									
										
										
										
											2019-11-13 06:50:18 +08:00
										 |  |  | 	if r.ContentLength < 0 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errInvalidArgument) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	err := gob.NewDecoder(r.Body).Decode(&retention) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-21 05:18:09 +08:00
										 |  |  | 	globalBucketObjectLockConfig.Set(bucketName, retention) | 
					
						
							| 
									
										
										
										
											2019-11-13 06:50:18 +08:00
										 |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | // ServerUpdateHandler - updates the current server.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ServerUpdateHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	updateURL := vars[peerRESTUpdateURL] | 
					
						
							|  |  |  | 	sha256Hex := vars[peerRESTSha256Hex] | 
					
						
							|  |  |  | 	var latestReleaseTime time.Time | 
					
						
							|  |  |  | 	var err error | 
					
						
							|  |  |  | 	if latestRelease := vars[peerRESTLatestRelease]; latestRelease != "" { | 
					
						
							|  |  |  | 		latestReleaseTime, err = time.Parse(latestRelease, time.RFC3339) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	us, err := updateServer(updateURL, sha256Hex, latestReleaseTime) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if us.CurrentVersion != us.UpdatedVersion { | 
					
						
							|  |  |  | 		globalServiceSignalCh <- serviceRestart | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | var errUnsupportedSignal = fmt.Errorf("unsupported signal: only restart and stop signals are supported") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // SignalServiceHandler - signal service handler.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) SignalServiceHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	vars := mux.Vars(r) | 
					
						
							|  |  |  | 	signalString := vars[peerRESTSignal] | 
					
						
							|  |  |  | 	if signalString == "" { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("signal name is missing")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2019-08-28 02:37:47 +08:00
										 |  |  | 	si, err := strconv.Atoi(signalString) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	signal := serviceSignal(si) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 	switch signal { | 
					
						
							|  |  |  | 	case serviceRestart: | 
					
						
							|  |  |  | 		globalServiceSignalCh <- signal | 
					
						
							|  |  |  | 	case serviceStop: | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | 		globalServiceSignalCh <- signal | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errUnsupportedSignal) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | // ListenHandler sends http trace messages back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ListenHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	values := r.URL.Query() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var prefix string | 
					
						
							|  |  |  | 	if len(values[peerRESTListenPrefix]) > 1 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(values[peerRESTListenPrefix]) == 1 { | 
					
						
							|  |  |  | 		if err := event.ValidateFilterRuleValue(values[peerRESTListenPrefix][0]); err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		prefix = values[peerRESTListenPrefix][0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var suffix string | 
					
						
							|  |  |  | 	if len(values[peerRESTListenSuffix]) > 1 { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if len(values[peerRESTListenSuffix]) == 1 { | 
					
						
							|  |  |  | 		if err := event.ValidateFilterRuleValue(values[peerRESTListenSuffix][0]); err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		suffix = values[peerRESTListenSuffix][0] | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	pattern := event.NewPattern(prefix, suffix) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	var eventNames []event.Name | 
					
						
							|  |  |  | 	for _, ev := range values[peerRESTListenEvents] { | 
					
						
							|  |  |  | 		eventName, err := event.ParseName(ev) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		eventNames = append(eventNames, eventName) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	rulesMap := event.NewRulesMap(eventNames, pattern, event.TargetID{ID: mustGetUUID()}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 	w.WriteHeader(http.StatusOK) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	doneCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(doneCh) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Listen Publisher uses nonblocking publish and hence does not wait for slow subscribers.
 | 
					
						
							|  |  |  | 	// Use buffered channel to take care of burst sends or slow w.Write()
 | 
					
						
							|  |  |  | 	ch := make(chan interface{}, 2000) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	globalHTTPListen.Subscribe(ch, doneCh, func(evI interface{}) bool { | 
					
						
							|  |  |  | 		ev, ok := evI.(event.Event) | 
					
						
							|  |  |  | 		if !ok { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-21 03:45:03 +08:00
										 |  |  | 		if ev.S3.Bucket.Name != values.Get(peerRESTListenBucket) { | 
					
						
							|  |  |  | 			return false | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 		objectName, uerr := url.QueryUnescape(ev.S3.Object.Key) | 
					
						
							|  |  |  | 		if uerr != nil { | 
					
						
							|  |  |  | 			objectName = ev.S3.Object.Key | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return len(rulesMap.Match(ev.EventName, objectName).ToSlice()) != 0 | 
					
						
							| 
									
										
										
										
											2019-12-13 02:01:23 +08:00
										 |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	keepAliveTicker := time.NewTicker(500 * time.Millisecond) | 
					
						
							|  |  |  | 	defer keepAliveTicker.Stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case ev := <-ch: | 
					
						
							|  |  |  | 			if err := enc.Encode(ev); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 		case <-keepAliveTicker.C: | 
					
						
							|  |  |  | 			if err := enc.Encode(&event.Event{}); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | // TraceHandler sends http trace messages back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) TraceHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	trcAll := r.URL.Query().Get(peerRESTTraceAll) == "true" | 
					
						
							| 
									
										
										
										
											2019-07-20 08:38:26 +08:00
										 |  |  | 	trcErr := r.URL.Query().Get(peerRESTTraceErr) == "true" | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	w.WriteHeader(http.StatusOK) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 	doneCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(doneCh) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Trace Publisher uses nonblocking publish and hence does not wait for slow subscribers.
 | 
					
						
							|  |  |  | 	// Use buffered channel to take care of burst sends or slow w.Write()
 | 
					
						
							|  |  |  | 	ch := make(chan interface{}, 2000) | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	globalHTTPTrace.Subscribe(ch, doneCh, func(entry interface{}) bool { | 
					
						
							|  |  |  | 		return mustTrace(entry, trcAll, trcErr) | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	keepAliveTicker := time.NewTicker(500 * time.Millisecond) | 
					
						
							|  |  |  | 	defer keepAliveTicker.Stop() | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case entry := <-ch: | 
					
						
							| 
									
										
										
										
											2019-06-27 13:41:12 +08:00
										 |  |  | 			if err := enc.Encode(entry); err != nil { | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							| 
									
										
										
										
											2019-08-01 02:08:39 +08:00
										 |  |  | 		case <-keepAliveTicker.C: | 
					
						
							|  |  |  | 			if err := enc.Encode(&trace.Info{}); err != nil { | 
					
						
							|  |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							| 
									
										
										
										
											2019-06-09 06:54:41 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-26 07:42:24 +08:00
										 |  |  | func (s *peerRESTServer) BackgroundHealStatusHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "BackgroundHealStatus") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	state := getLocalBackgroundHealStatus() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(state)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-10 01:02:41 +08:00
										 |  |  | func (s *peerRESTServer) BackgroundOpsStatusHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ctx := newContext(r, w, "BackgroundOpsStatus") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	state := BgOpsStatus{ | 
					
						
							|  |  |  | 		LifecycleOps: getLocalBgLifecycleOpsStatus(), | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	defer w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 	logger.LogIf(ctx, gob.NewEncoder(w).Encode(state)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | // ConsoleLogHandler sends console logs of this node back to peer rest client
 | 
					
						
							|  |  |  | func (s *peerRESTServer) ConsoleLogHandler(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	if !s.IsValid(w, r) { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, errors.New("Invalid request")) | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	w.Header().Set("Connection", "close") | 
					
						
							|  |  |  | 	w.WriteHeader(http.StatusOK) | 
					
						
							|  |  |  | 	w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	doneCh := make(chan struct{}) | 
					
						
							|  |  |  | 	defer close(doneCh) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ch := make(chan interface{}, 2000) | 
					
						
							| 
									
										
										
										
											2019-10-12 09:50:54 +08:00
										 |  |  | 	globalConsoleSys.Subscribe(ch, doneCh, "", 0, string(logger.All), nil) | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	enc := gob.NewEncoder(w) | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							|  |  |  | 		case entry := <-ch: | 
					
						
							| 
									
										
										
										
											2019-09-22 16:24:32 +08:00
										 |  |  | 			if err := enc.Encode(entry); err != nil { | 
					
						
							| 
									
										
										
										
											2019-09-04 02:10:48 +08:00
										 |  |  | 				return | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			w.(http.Flusher).Flush() | 
					
						
							|  |  |  | 		case <-r.Context().Done(): | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | func (s *peerRESTServer) writeErrorResponse(w http.ResponseWriter, err error) { | 
					
						
							|  |  |  | 	w.WriteHeader(http.StatusForbidden) | 
					
						
							|  |  |  | 	w.Write([]byte(err.Error())) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // IsValid - To authenticate and verify the time difference.
 | 
					
						
							|  |  |  | func (s *peerRESTServer) IsValid(w http.ResponseWriter, r *http.Request) bool { | 
					
						
							|  |  |  | 	if err := storageServerRequestValidate(r); err != nil { | 
					
						
							|  |  |  | 		s.writeErrorResponse(w, err) | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // registerPeerRESTHandlers - register peer rest router.
 | 
					
						
							|  |  |  | func registerPeerRESTHandlers(router *mux.Router) { | 
					
						
							|  |  |  | 	server := &peerRESTServer{} | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter := router.PathPrefix(peerRESTPrefix).Subrouter() | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodNetReadPerfInfo).HandlerFunc(httpTraceHdrs(server.NetReadPerfInfoHandler)).Queries(restQueries(peerRESTNetPerfSize)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodCollectNetPerfInfo).HandlerFunc(httpTraceHdrs(server.CollectNetPerfInfoHandler)).Queries(restQueries(peerRESTNetPerfSize)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodGetLocks).HandlerFunc(httpTraceHdrs(server.GetLocksHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodServerInfo).HandlerFunc(httpTraceHdrs(server.ServerInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodCPULoadInfo).HandlerFunc(httpTraceHdrs(server.CPULoadInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodMemUsageInfo).HandlerFunc(httpTraceHdrs(server.MemUsageInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDrivePerfInfo).HandlerFunc(httpTraceHdrs(server.DrivePerfInfoHandler)).Queries(restQueries(peerRESTDrivePerfSize)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodHardwareCPUInfo).HandlerFunc(httpTraceHdrs(server.CPUInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodHardwareNetworkInfo).HandlerFunc(httpTraceHdrs(server.NetworkInfoHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteBucket).HandlerFunc(httpTraceHdrs(server.DeleteBucketHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSignalService).HandlerFunc(httpTraceHdrs(server.SignalServiceHandler)).Queries(restQueries(peerRESTSignal)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodServerUpdate).HandlerFunc(httpTraceHdrs(server.ServerUpdateHandler)).Queries(restQueries(peerRESTUpdateURL, peerRESTSha256Hex, peerRESTLatestRelease)...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketPolicyRemove).HandlerFunc(httpTraceAll(server.RemoveBucketPolicyHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketPolicySet).HandlerFunc(httpTraceHdrs(server.SetBucketPolicyHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeletePolicy).HandlerFunc(httpTraceAll(server.DeletePolicyHandler)).Queries(restQueries(peerRESTPolicy)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadPolicy).HandlerFunc(httpTraceAll(server.LoadPolicyHandler)).Queries(restQueries(peerRESTPolicy)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadPolicyMapping).HandlerFunc(httpTraceAll(server.LoadPolicyMappingHandler)).Queries(restQueries(peerRESTUserOrGroup)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDeleteUser).HandlerFunc(httpTraceAll(server.LoadUserHandler)).Queries(restQueries(peerRESTUser)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadUser).HandlerFunc(httpTraceAll(server.LoadUserHandler)).Queries(restQueries(peerRESTUser, peerRESTUserTemp)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadUsers).HandlerFunc(httpTraceAll(server.LoadUsersHandler)) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLoadGroup).HandlerFunc(httpTraceAll(server.LoadGroupHandler)).Queries(restQueries(peerRESTGroup)...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodStartProfiling).HandlerFunc(httpTraceAll(server.StartProfilingHandler)).Queries(restQueries(peerRESTProfiler)...) | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodDownloadProfilingData).HandlerFunc(httpTraceHdrs(server.DownloadProfilingDataHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodTargetExists).HandlerFunc(httpTraceHdrs(server.TargetExistsHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodSendEvent).HandlerFunc(httpTraceHdrs(server.SendEventHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketNotificationPut).HandlerFunc(httpTraceHdrs(server.PutBucketNotificationHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodReloadFormat).HandlerFunc(httpTraceHdrs(server.ReloadFormatHandler)).Queries(restQueries(peerRESTDryRun)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketLifecycleSet).HandlerFunc(httpTraceHdrs(server.SetBucketLifecycleHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketLifecycleRemove).HandlerFunc(httpTraceHdrs(server.RemoveBucketLifecycleHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							| 
									
										
										
										
											2020-02-05 17:42:34 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketEncryptionSet).HandlerFunc(httpTraceHdrs(server.SetBucketSSEConfigHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketEncryptionRemove).HandlerFunc(httpTraceHdrs(server.RemoveBucketSSEConfigHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBackgroundOpsStatus).HandlerFunc(server.BackgroundOpsStatusHandler) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodTrace).HandlerFunc(server.TraceHandler) | 
					
						
							| 
									
										
										
										
											2019-12-17 12:30:57 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodListen).HandlerFunc(httpTraceHdrs(server.ListenHandler)) | 
					
						
							| 
									
										
										
										
											2019-11-05 01:30:59 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBackgroundHealStatus).HandlerFunc(server.BackgroundHealStatusHandler) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodLog).HandlerFunc(server.ConsoleLogHandler) | 
					
						
							| 
									
										
										
										
											2019-11-22 05:18:32 +08:00
										 |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodPutBucketObjectLockConfig).HandlerFunc(httpTraceHdrs(server.PutBucketObjectLockConfigHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							|  |  |  | 	subrouter.Methods(http.MethodPost).Path(peerRESTVersionPrefix + peerRESTMethodBucketObjectLockConfigRemove).HandlerFunc(httpTraceHdrs(server.RemoveBucketObjectLockConfigHandler)).Queries(restQueries(peerRESTBucket)...) | 
					
						
							| 
									
										
										
										
											2019-03-15 07:27:31 +08:00
										 |  |  | } |