...
1 package handlers
2
3 import (
4 "net/http"
5
6 "github.com/docker/distribution"
7 "github.com/docker/distribution/context"
8 "github.com/docker/distribution/registry/api/errcode"
9 v2 "github.com/docker/distribution/registry/api/v2"
10 "github.com/gorilla/handlers"
11 "github.com/opencontainers/go-digest"
12 )
13
14
15 func blobDispatcher(ctx *Context, r *http.Request) http.Handler {
16 dgst, err := getDigest(ctx)
17 if err != nil {
18
19 if err == errDigestNotAvailable {
20 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
21 ctx.Errors = append(ctx.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
22 })
23 }
24
25 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26 ctx.Errors = append(ctx.Errors, v2.ErrorCodeDigestInvalid.WithDetail(err))
27 })
28 }
29
30 blobHandler := &blobHandler{
31 Context: ctx,
32 Digest: dgst,
33 }
34
35 mhandler := handlers.MethodHandler{
36 "GET": http.HandlerFunc(blobHandler.GetBlob),
37 "HEAD": http.HandlerFunc(blobHandler.GetBlob),
38 }
39
40 if !ctx.readOnly {
41 mhandler["DELETE"] = http.HandlerFunc(blobHandler.DeleteBlob)
42 }
43
44 return mhandler
45 }
46
47
48 type blobHandler struct {
49 *Context
50
51 Digest digest.Digest
52 }
53
54
55
56 func (bh *blobHandler) GetBlob(w http.ResponseWriter, r *http.Request) {
57 context.GetLogger(bh).Debug("GetBlob")
58 blobs := bh.Repository.Blobs(bh)
59 desc, err := blobs.Stat(bh, bh.Digest)
60 if err != nil {
61 if err == distribution.ErrBlobUnknown {
62 bh.Errors = append(bh.Errors, v2.ErrorCodeBlobUnknown.WithDetail(bh.Digest))
63 } else {
64 bh.Errors = append(bh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
65 }
66 return
67 }
68
69 if err := blobs.ServeBlob(bh, w, r, desc.Digest); err != nil {
70 context.GetLogger(bh).Debugf("unexpected error getting blob HTTP handler: %v", err)
71 bh.Errors = append(bh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
72 return
73 }
74 }
75
76
77 func (bh *blobHandler) DeleteBlob(w http.ResponseWriter, r *http.Request) {
78 context.GetLogger(bh).Debug("DeleteBlob")
79
80 blobs := bh.Repository.Blobs(bh)
81 err := blobs.Delete(bh, bh.Digest)
82 if err != nil {
83 switch err {
84 case distribution.ErrUnsupported:
85 bh.Errors = append(bh.Errors, errcode.ErrorCodeUnsupported)
86 return
87 case distribution.ErrBlobUnknown:
88 bh.Errors = append(bh.Errors, v2.ErrorCodeBlobUnknown)
89 return
90 default:
91 bh.Errors = append(bh.Errors, err)
92 context.GetLogger(bh).Errorf("Unknown error deleting blob: %s", err.Error())
93 return
94 }
95 }
96
97 w.Header().Set("Content-Length", "0")
98 w.WriteHeader(http.StatusAccepted)
99 }
100
View as plain text