| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | package minioapi | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/minio-io/minio/pkg/utils/config" | 
					
						
							|  |  |  | 	"github.com/minio-io/minio/pkg/utils/crypto/signers" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type vHandler struct { | 
					
						
							|  |  |  | 	conf    config.Config | 
					
						
							|  |  |  | 	handler http.Handler | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // grab AccessKey from authorization header
 | 
					
						
							|  |  |  | func stripAccessKey(r *http.Request) string { | 
					
						
							|  |  |  | 	fields := strings.Fields(r.Header.Get("Authorization")) | 
					
						
							|  |  |  | 	if len(fields) < 2 { | 
					
						
							|  |  |  | 		return "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	splits := strings.Split(fields[1], ":") | 
					
						
							|  |  |  | 	if len(splits) < 2 { | 
					
						
							|  |  |  | 		return "" | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return splits[0] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func validateHandler(conf config.Config, h http.Handler) http.Handler { | 
					
						
							|  |  |  | 	return vHandler{conf, h} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (h vHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | 
					
						
							|  |  |  | 	accessKey := stripAccessKey(r) | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 	acceptsContentType := getContentType(r) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 	if accessKey != "" { | 
					
						
							|  |  |  | 		if err := h.conf.ReadConfig(); err != nil { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 			error := errorCodeError(InternalError) | 
					
						
							|  |  |  | 			errorResponse := getErrorResponse(error, "") | 
					
						
							|  |  |  | 			w.WriteHeader(error.HttpStatusCode) | 
					
						
							|  |  |  | 			w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			user := h.conf.GetKey(accessKey) | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 			ok, _ := signers.ValidateRequest(user, r) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 			if ok { | 
					
						
							|  |  |  | 				h.handler.ServeHTTP(w, r) | 
					
						
							|  |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 				error := errorCodeError(AccessDenied) | 
					
						
							|  |  |  | 				errorResponse := getErrorResponse(error, "") | 
					
						
							|  |  |  | 				w.WriteHeader(error.HttpStatusCode) | 
					
						
							|  |  |  | 				w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		//No access key found, handle this more appropriately
 | 
					
						
							|  |  |  | 		//TODO: Remove this after adding tests to support signature
 | 
					
						
							|  |  |  | 		//request
 | 
					
						
							|  |  |  | 		h.handler.ServeHTTP(w, r) | 
					
						
							|  |  |  | 		//Add this line, to reply back for invalid requests
 | 
					
						
							|  |  |  | 		//w.WriteHeader(http.StatusUnauthorized)
 | 
					
						
							|  |  |  | 		//w.Write([]byte("Authorization header malformed")
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func ignoreUnimplementedResources(h http.Handler) http.Handler { | 
					
						
							|  |  |  | 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 		acceptsContentType := getContentType(r) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 		if ignoreUnImplementedObjectResources(r) || ignoreUnImplementedBucketResources(r) { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:00:45 +08:00
										 |  |  | 			error := errorCodeError(NotImplemented) | 
					
						
							|  |  |  | 			errorResponse := getErrorResponse(error, "") | 
					
						
							|  |  |  | 			w.WriteHeader(error.HttpStatusCode) | 
					
						
							|  |  |  | 			w.Write(writeErrorResponse(w, errorResponse, acceptsContentType)) | 
					
						
							| 
									
										
										
										
											2015-02-11 19:23:15 +08:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			h.ServeHTTP(w, r) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	}) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //// helpers
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Checks requests for unimplemented resources
 | 
					
						
							|  |  |  | func ignoreUnImplementedBucketResources(req *http.Request) bool { | 
					
						
							|  |  |  | 	q := req.URL.Query() | 
					
						
							|  |  |  | 	for name := range q { | 
					
						
							|  |  |  | 		if unimplementedBucketResourceNames[name] { | 
					
						
							|  |  |  | 			return true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func ignoreUnImplementedObjectResources(req *http.Request) bool { | 
					
						
							|  |  |  | 	q := req.URL.Query() | 
					
						
							|  |  |  | 	for name := range q { | 
					
						
							|  |  |  | 		if unimplementedObjectResourceNames[name] { | 
					
						
							|  |  |  | 			return true | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | } |