forked from TrueCloudLab/distribution
Merge pull request #2930 from dmathieu/extract-blob-resume
Extract blob upload resume into its own method
This commit is contained in:
commit
ec84b86013
1 changed files with 54 additions and 47 deletions
|
@ -9,7 +9,7 @@ import (
|
||||||
dcontext "github.com/docker/distribution/context"
|
dcontext "github.com/docker/distribution/context"
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/docker/distribution/reference"
|
||||||
"github.com/docker/distribution/registry/api/errcode"
|
"github.com/docker/distribution/registry/api/errcode"
|
||||||
"github.com/docker/distribution/registry/api/v2"
|
v2 "github.com/docker/distribution/registry/api/v2"
|
||||||
"github.com/docker/distribution/registry/storage"
|
"github.com/docker/distribution/registry/storage"
|
||||||
"github.com/gorilla/handlers"
|
"github.com/gorilla/handlers"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
|
@ -36,52 +36,8 @@ func blobUploadDispatcher(ctx *Context, r *http.Request) http.Handler {
|
||||||
}
|
}
|
||||||
|
|
||||||
if buh.UUID != "" {
|
if buh.UUID != "" {
|
||||||
state, err := hmacKey(ctx.Config.HTTP.Secret).unpackUploadState(r.FormValue("_state"))
|
if h := buh.ResumeBlobUpload(ctx, r); h != nil {
|
||||||
if err != nil {
|
return h
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
dcontext.GetLogger(ctx).Infof("error resolving upload: %v", err)
|
|
||||||
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
buh.State = state
|
|
||||||
|
|
||||||
if state.Name != ctx.Repository.Named().Name() {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
dcontext.GetLogger(ctx).Infof("mismatched repository name in upload state: %q != %q", state.Name, buh.Repository.Named().Name())
|
|
||||||
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if state.UUID != buh.UUID {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
dcontext.GetLogger(ctx).Infof("mismatched uuid in upload state: %q != %q", state.UUID, buh.UUID)
|
|
||||||
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
blobs := ctx.Repository.Blobs(buh)
|
|
||||||
upload, err := blobs.Resume(buh, buh.UUID)
|
|
||||||
if err != nil {
|
|
||||||
dcontext.GetLogger(ctx).Errorf("error resolving upload: %v", err)
|
|
||||||
if err == distribution.ErrBlobUploadUnknown {
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown.WithDetail(err))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
buh.Upload = upload
|
|
||||||
|
|
||||||
if size := upload.Size(); size != buh.State.Offset {
|
|
||||||
defer upload.Close()
|
|
||||||
dcontext.GetLogger(ctx).Errorf("upload resumed at wrong offset: %d != %d", size, buh.State.Offset)
|
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
|
||||||
upload.Cancel(buh)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return closeResources(handler, buh.Upload)
|
return closeResources(handler, buh.Upload)
|
||||||
}
|
}
|
||||||
|
@ -282,6 +238,57 @@ func (buh *blobUploadHandler) CancelBlobUpload(w http.ResponseWriter, r *http.Re
|
||||||
w.WriteHeader(http.StatusNoContent)
|
w.WriteHeader(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (buh *blobUploadHandler) ResumeBlobUpload(ctx *Context, r *http.Request) http.Handler {
|
||||||
|
state, err := hmacKey(ctx.Config.HTTP.Secret).unpackUploadState(r.FormValue("_state"))
|
||||||
|
if err != nil {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
dcontext.GetLogger(ctx).Infof("error resolving upload: %v", err)
|
||||||
|
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
buh.State = state
|
||||||
|
|
||||||
|
if state.Name != ctx.Repository.Named().Name() {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
dcontext.GetLogger(ctx).Infof("mismatched repository name in upload state: %q != %q", state.Name, buh.Repository.Named().Name())
|
||||||
|
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if state.UUID != buh.UUID {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
dcontext.GetLogger(ctx).Infof("mismatched uuid in upload state: %q != %q", state.UUID, buh.UUID)
|
||||||
|
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
blobs := ctx.Repository.Blobs(buh)
|
||||||
|
upload, err := blobs.Resume(buh, buh.UUID)
|
||||||
|
if err != nil {
|
||||||
|
dcontext.GetLogger(ctx).Errorf("error resolving upload: %v", err)
|
||||||
|
if err == distribution.ErrBlobUploadUnknown {
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadUnknown.WithDetail(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
buh.Errors = append(buh.Errors, errcode.ErrorCodeUnknown.WithDetail(err))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
buh.Upload = upload
|
||||||
|
|
||||||
|
if size := upload.Size(); size != buh.State.Offset {
|
||||||
|
defer upload.Close()
|
||||||
|
dcontext.GetLogger(ctx).Errorf("upload resumed at wrong offset: %d != %d", size, buh.State.Offset)
|
||||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
buh.Errors = append(buh.Errors, v2.ErrorCodeBlobUploadInvalid.WithDetail(err))
|
||||||
|
upload.Cancel(buh)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// blobUploadResponse provides a standard request for uploading blobs and
|
// blobUploadResponse provides a standard request for uploading blobs and
|
||||||
// chunk responses. This sets the correct headers but the response status is
|
// chunk responses. This sets the correct headers but the response status is
|
||||||
// left to the caller. The fresh argument is used to ensure that new blob
|
// left to the caller. The fresh argument is used to ensure that new blob
|
||||||
|
|
Loading…
Reference in a new issue