2015-02-11 01:25:40 +00:00
|
|
|
package handlers
|
2015-01-06 18:37:27 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
|
2015-02-12 00:49:49 +00:00
|
|
|
"github.com/docker/distribution"
|
2015-04-27 22:58:58 +00:00
|
|
|
"github.com/docker/distribution/context"
|
2015-01-06 18:37:27 +00:00
|
|
|
"github.com/docker/distribution/digest"
|
2015-02-11 02:18:45 +00:00
|
|
|
"github.com/docker/distribution/registry/api/v2"
|
2015-01-06 18:37:27 +00:00
|
|
|
"github.com/gorilla/handlers"
|
|
|
|
)
|
|
|
|
|
|
|
|
// layerDispatcher uses the request context to build a layerHandler.
|
|
|
|
func layerDispatcher(ctx *Context, r *http.Request) http.Handler {
|
2015-02-07 00:19:19 +00:00
|
|
|
dgst, err := getDigest(ctx)
|
2015-01-06 18:37:27 +00:00
|
|
|
if err != nil {
|
2015-02-07 00:19:19 +00:00
|
|
|
|
|
|
|
if err == errDigestNotAvailable {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
ctx.Errors.Push(v2.ErrorCodeDigestInvalid, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2015-01-06 18:37:27 +00:00
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
ctx.Errors.Push(v2.ErrorCodeDigestInvalid, err)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
layerHandler := &layerHandler{
|
|
|
|
Context: ctx,
|
|
|
|
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) {
|
2015-04-27 22:58:58 +00:00
|
|
|
context.GetLogger(lh).Debug("GetImageLayer")
|
2015-03-06 17:48:25 +00:00
|
|
|
layers := lh.Repository.Layers()
|
|
|
|
layer, err := layers.Fetch(lh.Digest)
|
2015-01-06 18:37:27 +00:00
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
switch err := err.(type) {
|
2015-02-12 00:49:49 +00:00
|
|
|
case distribution.ErrUnknownLayer:
|
2015-01-06 18:37:27 +00:00
|
|
|
w.WriteHeader(http.StatusNotFound)
|
|
|
|
lh.Errors.Push(v2.ErrorCodeBlobUnknown, err.FSLayer)
|
|
|
|
default:
|
|
|
|
lh.Errors.Push(v2.ErrorCodeUnknown, err)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-03-13 02:31:41 +00:00
|
|
|
handler, err := layer.Handler(r)
|
|
|
|
if err != nil {
|
2015-04-27 22:58:58 +00:00
|
|
|
context.GetLogger(lh).Debugf("unexpected error getting layer HTTP handler: %s", err)
|
2015-03-13 02:31:41 +00:00
|
|
|
lh.Errors.Push(v2.ErrorCodeUnknown, err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
handler.ServeHTTP(w, r)
|
2015-01-06 18:37:27 +00:00
|
|
|
}
|