69 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			69 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			Go
		
	
	
| package registry
 | |
| 
 | |
| import (
 | |
| 	"net/http"
 | |
| 
 | |
| 	"github.com/docker/distribution/api/v2"
 | |
| 	"github.com/docker/distribution/digest"
 | |
| 	"github.com/docker/distribution/storage"
 | |
| 	"github.com/gorilla/handlers"
 | |
| )
 | |
| 
 | |
| // layerDispatcher uses the request context to build a layerHandler.
 | |
| func layerDispatcher(ctx *Context, r *http.Request) http.Handler {
 | |
| 	dgst, err := digest.ParseDigest(ctx.vars["digest"])
 | |
| 
 | |
| 	if err != nil {
 | |
| 		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 | |
| 			ctx.Errors.Push(v2.ErrorCodeDigestInvalid, err)
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	layerHandler := &layerHandler{
 | |
| 		Context: ctx,
 | |
| 		Digest:  dgst,
 | |
| 	}
 | |
| 
 | |
| 	layerHandler.log = layerHandler.log.WithField("digest", dgst)
 | |
| 
 | |
| 	return handlers.MethodHandler{
 | |
| 		"GET":  http.HandlerFunc(layerHandler.GetLayer),
 | |
| 		"HEAD": http.HandlerFunc(layerHandler.GetLayer),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // layerHandler serves http layer requests.
 | |
| type layerHandler struct {
 | |
| 	*Context
 | |
| 
 | |
| 	Digest digest.Digest
 | |
| }
 | |
| 
 | |
| // GetLayer fetches the binary data from backend storage returns it in the
 | |
| // response.
 | |
| func (lh *layerHandler) GetLayer(w http.ResponseWriter, r *http.Request) {
 | |
| 	layers := lh.services.Layers()
 | |
| 
 | |
| 	layer, err := layers.Fetch(lh.Name, lh.Digest)
 | |
| 
 | |
| 	if err != nil {
 | |
| 		switch err := err.(type) {
 | |
| 		case storage.ErrUnknownLayer:
 | |
| 			w.WriteHeader(http.StatusNotFound)
 | |
| 			lh.Errors.Push(v2.ErrorCodeBlobUnknown, err.FSLayer)
 | |
| 		default:
 | |
| 			lh.Errors.Push(v2.ErrorCodeUnknown, err)
 | |
| 		}
 | |
| 		return
 | |
| 	}
 | |
| 	defer layer.Close()
 | |
| 
 | |
| 	handler, err := lh.layerHandler.Resolve(layer)
 | |
| 	if handler != nil {
 | |
| 		handler.ServeHTTP(w, r)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	http.ServeContent(w, r, layer.Digest().String(), layer.CreatedAt(), layer)
 | |
| }
 |