github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/httpcontext/model.go (about) 1 // Copyright 2018 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package httpcontext 5 6 import ( 7 "context" 8 "fmt" 9 "net/http" 10 11 "gopkg.in/juju/names.v2" 12 ) 13 14 // ImpliedModelHandler is an http.Handler that associates requests that 15 // it handles with a specified model UUID. The model UUID can then be 16 // extracted using the RequestModel function in this package. 17 type ImpliedModelHandler struct { 18 http.Handler 19 ModelUUID string 20 } 21 22 // ServeHTTP is part of the http.Handler interface. 23 func (h *ImpliedModelHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { 24 ctx := context.WithValue(req.Context(), modelKey{}, h.ModelUUID) 25 req = req.WithContext(ctx) 26 h.Handler.ServeHTTP(w, req) 27 } 28 29 // QueryModelHandler is an http.Handler that associates requests that 30 // it handles with a model UUID extracted from a specified query parameter. 31 // The model UUID can then be extracted using the RequestModel function 32 // in this package. 33 type QueryModelHandler struct { 34 http.Handler 35 Query string 36 } 37 38 // ServeHTTP is part of the http.Handler interface. 39 func (h *QueryModelHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { 40 modelUUID := req.URL.Query().Get(h.Query) 41 if modelUUID != "" { 42 if !names.IsValidModel(modelUUID) { 43 http.Error(w, 44 fmt.Sprintf("invalid model UUID %q", modelUUID), 45 http.StatusBadRequest, 46 ) 47 return 48 } 49 ctx := context.WithValue(req.Context(), modelKey{}, modelUUID) 50 req = req.WithContext(ctx) 51 } 52 h.Handler.ServeHTTP(w, req) 53 } 54 55 type modelKey struct{} 56 57 // RequestModelUUID returns the model UUID associated with this request 58 // if there is one, or the empty string otherwise. No attempt is made 59 // to validate the model UUID; QueryModelHandler does this, and 60 // ImpliedModelHandler should always be supplied with a valid UUID. 61 func RequestModelUUID(req *http.Request) string { 62 if value := req.Context().Value(modelKey{}); value != nil { 63 return value.(string) 64 } 65 return "" 66 }