github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/resource/api/server/handler.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package server
     5  
     6  import (
     7  	"net/http"
     8  
     9  	"github.com/juju/errors"
    10  	"gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/resource/api"
    13  )
    14  
    15  // LegacyHTTPHandler is the HTTP handler for the resources endpoint. We
    16  // use it rather having a separate handler for each HTTP method since
    17  // registered API handlers must handle *all* HTTP methods currently.
    18  type LegacyHTTPHandler struct {
    19  	// Connect opens a connection to state resources.
    20  	Connect func(*http.Request) (DataStore, names.Tag, error)
    21  
    22  	// HandleUpload provides the upload functionality.
    23  	HandleUpload func(username string, st DataStore, req *http.Request) (*api.UploadResult, error)
    24  }
    25  
    26  // TODO(ericsnow) Can username be extracted from the request?
    27  
    28  // NewLegacyHTTPHandler creates a new http.Handler for the resources endpoint.
    29  func NewLegacyHTTPHandler(connect func(*http.Request) (DataStore, names.Tag, error)) *LegacyHTTPHandler {
    30  	return &LegacyHTTPHandler{
    31  		Connect: connect,
    32  		HandleUpload: func(username string, st DataStore, req *http.Request) (*api.UploadResult, error) {
    33  			uh := UploadHandler{
    34  				Username: username,
    35  				Store:    st,
    36  			}
    37  			return uh.HandleRequest(req)
    38  		},
    39  	}
    40  }
    41  
    42  // ServeHTTP implements http.Handler.
    43  func (h *LegacyHTTPHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
    44  	st, tag, err := h.Connect(req)
    45  	if err != nil {
    46  		api.SendHTTPError(resp, err)
    47  		return
    48  	}
    49  
    50  	var username string
    51  	switch tag := tag.(type) {
    52  	case *names.UserTag:
    53  		username = tag.Name()
    54  	default:
    55  		// TODO(ericsnow) Fail?
    56  		username = tag.Id()
    57  	}
    58  
    59  	// We do this *after* authorization, etc. (in h.Connect) in order
    60  	// to prioritize errors that may originate there.
    61  	switch req.Method {
    62  	case "PUT":
    63  		logger.Infof("handling resource upload request")
    64  		response, err := h.HandleUpload(username, st, req)
    65  		if err != nil {
    66  			api.SendHTTPError(resp, err)
    67  			return
    68  		}
    69  		api.SendHTTPStatusAndJSON(resp, http.StatusOK, &response)
    70  		logger.Infof("resource upload request successful")
    71  	default:
    72  		api.SendHTTPError(resp, errors.MethodNotAllowedf("unsupported method: %q", req.Method))
    73  	}
    74  }