github.com/juju/juju@v0.0.0-20240430160146-1752b71fcf00/apiserver/resources_unit.go (about) 1 // Copyright 2017 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver 5 6 import ( 7 "fmt" 8 "io" 9 "net/http" 10 11 "github.com/juju/errors" 12 "github.com/juju/names/v5" 13 14 "github.com/juju/juju/core/resources" 15 "github.com/juju/juju/rpc/params" 16 "github.com/juju/juju/state" 17 ) 18 19 // UnitResourcesHandler is the HTTP handler for unit agent downloads of 20 // resources. 21 type UnitResourcesHandler struct { 22 NewOpener func(*http.Request, ...string) (resources.Opener, state.PoolHelper, error) 23 } 24 25 // ServeHTTP implements http.Handler. 26 func (h *UnitResourcesHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) { 27 switch req.Method { 28 case "GET": 29 opener, ph, err := h.NewOpener(req, names.UnitTagKind, names.ApplicationTagKind) 30 if err != nil { 31 if err := sendError(resp, err); err != nil { 32 logger.Errorf("%v", err) 33 } 34 return 35 } 36 defer ph.Release() 37 38 name := req.URL.Query().Get(":resource") 39 opened, err := opener.OpenResource(name) 40 if err != nil { 41 if errors.IsNotFound(err) { 42 // non internal errors is not real errors. 43 logger.Warningf("cannot fetch resource reader: %v", err) 44 } else { 45 logger.Errorf("cannot fetch resource reader: %v", err) 46 } 47 if err := sendError(resp, err); err != nil { 48 logger.Errorf("%v", err) 49 } 50 return 51 } 52 defer opened.Close() 53 54 hdr := resp.Header() 55 hdr.Set("Content-Type", params.ContentTypeRaw) 56 hdr.Set("Content-Length", fmt.Sprint(opened.Size)) 57 hdr.Set("Content-Sha384", opened.Fingerprint.String()) 58 59 resp.WriteHeader(http.StatusOK) 60 if _, err := io.Copy(resp, opened); err != nil { 61 // We cannot use SendHTTPError here, so we log the error 62 // and move on. 63 logger.Errorf("unable to complete stream for resource: %v", err) 64 return 65 } 66 default: 67 if err := sendError(resp, errors.MethodNotAllowedf("unsupported method: %q", req.Method)); err != nil { 68 logger.Errorf("%v", err) 69 } 70 } 71 }