github.com/lusis/distribution@v2.0.1+incompatible/registry/handlers/layer.go (about) 1 package handlers 2 3 import ( 4 "net/http" 5 6 "github.com/docker/distribution" 7 ctxu "github.com/docker/distribution/context" 8 "github.com/docker/distribution/digest" 9 "github.com/docker/distribution/registry/api/v2" 10 "github.com/gorilla/handlers" 11 ) 12 13 // layerDispatcher uses the request context to build a layerHandler. 14 func layerDispatcher(ctx *Context, r *http.Request) http.Handler { 15 dgst, err := getDigest(ctx) 16 if err != nil { 17 18 if err == errDigestNotAvailable { 19 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 20 w.WriteHeader(http.StatusNotFound) 21 ctx.Errors.Push(v2.ErrorCodeDigestInvalid, err) 22 }) 23 } 24 25 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 26 ctx.Errors.Push(v2.ErrorCodeDigestInvalid, err) 27 }) 28 } 29 30 layerHandler := &layerHandler{ 31 Context: ctx, 32 Digest: dgst, 33 } 34 35 return handlers.MethodHandler{ 36 "GET": http.HandlerFunc(layerHandler.GetLayer), 37 "HEAD": http.HandlerFunc(layerHandler.GetLayer), 38 } 39 } 40 41 // layerHandler serves http layer requests. 42 type layerHandler struct { 43 *Context 44 45 Digest digest.Digest 46 } 47 48 // GetLayer fetches the binary data from backend storage returns it in the 49 // response. 50 func (lh *layerHandler) GetLayer(w http.ResponseWriter, r *http.Request) { 51 ctxu.GetLogger(lh).Debug("GetImageLayer") 52 layers := lh.Repository.Layers() 53 layer, err := layers.Fetch(lh.Digest) 54 55 if err != nil { 56 switch err := err.(type) { 57 case distribution.ErrUnknownLayer: 58 w.WriteHeader(http.StatusNotFound) 59 lh.Errors.Push(v2.ErrorCodeBlobUnknown, err.FSLayer) 60 default: 61 lh.Errors.Push(v2.ErrorCodeUnknown, err) 62 } 63 return 64 } 65 66 handler, err := layer.Handler(r) 67 if err != nil { 68 ctxu.GetLogger(lh).Debugf("unexpected error getting layer HTTP handler: %s", err) 69 lh.Errors.Push(v2.ErrorCodeUnknown, err) 70 return 71 } 72 73 handler.ServeHTTP(w, r) 74 }