2017-05-23 18:56:10 +00:00
|
|
|
package handler
|
2016-12-18 05:21:29 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2018-04-16 11:19:24 +00:00
|
|
|
"io/ioutil"
|
2016-12-18 05:21:29 +00:00
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
2017-05-23 18:56:10 +00:00
|
|
|
|
|
|
|
"github.com/portainer/portainer"
|
|
|
|
httperror "github.com/portainer/portainer/http/error"
|
2018-02-23 02:10:26 +00:00
|
|
|
"github.com/portainer/portainer/http/handler/extensions"
|
2016-12-18 05:21:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// Handler is a collection of all the service handlers.
|
|
|
|
type Handler struct {
|
2017-05-23 18:56:10 +00:00
|
|
|
AuthHandler *AuthHandler
|
|
|
|
UserHandler *UserHandler
|
|
|
|
TeamHandler *TeamHandler
|
|
|
|
TeamMembershipHandler *TeamMembershipHandler
|
|
|
|
EndpointHandler *EndpointHandler
|
2018-04-26 16:08:46 +00:00
|
|
|
EndpointGroupHandler *EndpointGroupHandler
|
2017-06-20 11:00:32 +00:00
|
|
|
RegistryHandler *RegistryHandler
|
|
|
|
DockerHubHandler *DockerHubHandler
|
2018-02-23 02:10:26 +00:00
|
|
|
ExtensionHandler *ExtensionHandler
|
|
|
|
StoridgeHandler *extensions.StoridgeHandler
|
2017-05-23 18:56:10 +00:00
|
|
|
ResourceHandler *ResourceHandler
|
2017-10-15 17:24:40 +00:00
|
|
|
StackHandler *StackHandler
|
2017-06-01 08:14:55 +00:00
|
|
|
StatusHandler *StatusHandler
|
2017-05-23 18:56:10 +00:00
|
|
|
SettingsHandler *SettingsHandler
|
|
|
|
TemplatesHandler *TemplatesHandler
|
|
|
|
DockerHandler *DockerHandler
|
2018-05-28 14:40:33 +00:00
|
|
|
AzureHandler *AzureHandler
|
2017-05-23 18:56:10 +00:00
|
|
|
WebSocketHandler *WebSocketHandler
|
|
|
|
UploadHandler *UploadHandler
|
|
|
|
FileHandler *FileHandler
|
2016-12-18 05:21:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
// ErrInvalidJSON defines an error raised the app is unable to parse request data
|
|
|
|
ErrInvalidJSON = portainer.Error("Invalid JSON")
|
|
|
|
// ErrInvalidRequestFormat defines an error raised when the format of the data sent in a request is not valid
|
|
|
|
ErrInvalidRequestFormat = portainer.Error("Invalid request data format")
|
2017-03-12 16:24:15 +00:00
|
|
|
// ErrInvalidQueryFormat defines an error raised when the data sent in the query or the URL is invalid
|
|
|
|
ErrInvalidQueryFormat = portainer.Error("Invalid query format")
|
2016-12-18 05:21:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// ServeHTTP delegates a request to the appropriate subhandler.
|
|
|
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2017-08-13 14:45:55 +00:00
|
|
|
|
|
|
|
switch {
|
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/auth"):
|
2016-12-18 05:21:29 +00:00
|
|
|
http.StripPrefix("/api", h.AuthHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/dockerhub"):
|
|
|
|
http.StripPrefix("/api", h.DockerHubHandler).ServeHTTP(w, r)
|
2018-04-26 16:08:46 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/endpoint_groups"):
|
|
|
|
http.StripPrefix("/api", h.EndpointGroupHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/endpoints"):
|
2018-02-23 02:10:26 +00:00
|
|
|
switch {
|
2018-03-12 23:06:38 +00:00
|
|
|
case strings.Contains(r.URL.Path, "/docker/"):
|
2017-07-20 14:22:27 +00:00
|
|
|
http.StripPrefix("/api/endpoints", h.DockerHandler).ServeHTTP(w, r)
|
2018-02-23 02:10:26 +00:00
|
|
|
case strings.Contains(r.URL.Path, "/stacks"):
|
2017-10-15 17:24:40 +00:00
|
|
|
http.StripPrefix("/api/endpoints", h.StackHandler).ServeHTTP(w, r)
|
2018-02-23 02:10:26 +00:00
|
|
|
case strings.Contains(r.URL.Path, "/extensions/storidge"):
|
|
|
|
http.StripPrefix("/api/endpoints", h.StoridgeHandler).ServeHTTP(w, r)
|
|
|
|
case strings.Contains(r.URL.Path, "/extensions"):
|
|
|
|
http.StripPrefix("/api/endpoints", h.ExtensionHandler).ServeHTTP(w, r)
|
2018-05-28 14:40:33 +00:00
|
|
|
case strings.Contains(r.URL.Path, "/azure/"):
|
|
|
|
http.StripPrefix("/api/endpoints", h.AzureHandler).ServeHTTP(w, r)
|
2018-02-23 02:10:26 +00:00
|
|
|
default:
|
2017-07-20 14:22:27 +00:00
|
|
|
http.StripPrefix("/api", h.EndpointHandler).ServeHTTP(w, r)
|
|
|
|
}
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/registries"):
|
2017-06-20 11:00:32 +00:00
|
|
|
http.StripPrefix("/api", h.RegistryHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/resource_controls"):
|
2017-05-23 18:56:10 +00:00
|
|
|
http.StripPrefix("/api", h.ResourceHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/settings"):
|
2016-12-18 05:21:29 +00:00
|
|
|
http.StripPrefix("/api", h.SettingsHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/status"):
|
2017-06-01 08:14:55 +00:00
|
|
|
http.StripPrefix("/api", h.StatusHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/templates"):
|
2016-12-18 05:21:29 +00:00
|
|
|
http.StripPrefix("/api", h.TemplatesHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/upload"):
|
2016-12-25 20:34:02 +00:00
|
|
|
http.StripPrefix("/api", h.UploadHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/users"):
|
|
|
|
http.StripPrefix("/api", h.UserHandler).ServeHTTP(w, r)
|
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/teams"):
|
|
|
|
http.StripPrefix("/api", h.TeamHandler).ServeHTTP(w, r)
|
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/team_memberships"):
|
|
|
|
http.StripPrefix("/api", h.TeamMembershipHandler).ServeHTTP(w, r)
|
|
|
|
case strings.HasPrefix(r.URL.Path, "/api/websocket"):
|
2016-12-18 05:21:29 +00:00
|
|
|
http.StripPrefix("/api", h.WebSocketHandler).ServeHTTP(w, r)
|
2017-08-13 14:45:55 +00:00
|
|
|
case strings.HasPrefix(r.URL.Path, "/"):
|
2016-12-18 05:21:29 +00:00
|
|
|
h.FileHandler.ServeHTTP(w, r)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-13 14:45:55 +00:00
|
|
|
// encodeJSON encodes v to w in JSON format. WriteErrorResponse() is called if encoding fails.
|
2016-12-18 05:21:29 +00:00
|
|
|
func encodeJSON(w http.ResponseWriter, v interface{}, logger *log.Logger) {
|
2018-04-13 14:01:02 +00:00
|
|
|
w.Header().Set("Content-Type", "application/json")
|
2016-12-18 05:21:29 +00:00
|
|
|
if err := json.NewEncoder(w).Encode(v); err != nil {
|
2017-05-23 18:56:10 +00:00
|
|
|
httperror.WriteErrorResponse(w, err, http.StatusInternalServerError, logger)
|
2016-12-18 05:21:29 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-16 11:19:24 +00:00
|
|
|
|
|
|
|
// getUploadedFileContent retrieve the content of a file uploaded in the request.
|
|
|
|
// Uses requestParameter as the key to retrieve the file in the request payload.
|
|
|
|
func getUploadedFileContent(request *http.Request, requestParameter string) ([]byte, error) {
|
|
|
|
file, _, err := request.FormFile(requestParameter)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
fileContent, err := ioutil.ReadAll(file)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return fileContent, nil
|
|
|
|
}
|