Merge pull request #9253 from heww/patch-blob-upload-improvement

Patch blob upload improvement
This commit is contained in:
Wenkai Yin(尹文开) 2019-09-26 13:59:15 +08:00 committed by GitHub
commit cabe0b6243
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 74 additions and 4 deletions

View File

@ -36,7 +36,7 @@ var (
}
)
// blobStreamUploadBuilder interceptor for PATCH /v2/<name>/blobs/uploads/<uuid>
// blobStreamUploadBuilder interceptor builder for PATCH /v2/<name>/blobs/uploads/<uuid>
type blobStreamUploadBuilder struct{}
func (*blobStreamUploadBuilder) Build(req *http.Request) (interceptor.Interceptor, error) {
@ -48,9 +48,13 @@ func (*blobStreamUploadBuilder) Build(req *http.Request) (interceptor.Intercepto
uuid := s[2]
onResponse := func(w http.ResponseWriter, req *http.Request) {
if !config.QuotaPerProjectEnable() {
return
}
size, err := parseUploadedBlobSize(w)
if err != nil {
log.Errorf("failed to parse uploaded blob size for upload %s", uuid)
log.Errorf("failed to parse uploaded blob size for upload %s, error: %v", uuid, err)
return
}

View File

@ -42,9 +42,16 @@ func parseUploadedBlobSize(w http.ResponseWriter) (int64, error) {
// Range: Range indicating the current progress of the upload.
// https://github.com/opencontainers/distribution-spec/blob/master/spec.md#get-blob-upload
r := w.Header().Get("Range")
if r == "" {
return 0, errors.New("range header not found")
}
end := strings.Split(r, "-")[1]
size, err := strconv.ParseInt(end, 10, 64)
parts := strings.SplitN(r, "-", 2)
if len(parts) != 2 {
return 0, fmt.Errorf("range header bad value: %s", r)
}
size, err := strconv.ParseInt(parts[1], 10, 64)
if err != nil {
return 0, err
}

View File

@ -0,0 +1,59 @@
// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package sizequota
import (
"net/http"
"net/http/httptest"
"testing"
)
func Test_parseUploadedBlobSize(t *testing.T) {
writer := func(header string) http.ResponseWriter {
rr := httptest.NewRecorder()
if header != "" {
rr.Header().Add("Range", header)
}
return rr
}
type args struct {
w http.ResponseWriter
}
tests := []struct {
name string
args args
want int64
wantErr bool
}{
{"success", args{writer("0-99")}, 100, false},
{"ranage header not found", args{writer("")}, 0, true},
{"ranage header bad value", args{writer("0")}, 0, true},
{"ranage header bad value", args{writer("0-")}, 0, true},
{"ranage header bad value", args{writer("0-a")}, 0, true},
{"ranage header bad value", args{writer("0-1-2")}, 0, true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseUploadedBlobSize(tt.args.w)
if (err != nil) != tt.wantErr {
t.Errorf("parseUploadedBlobSize() error = %v, wantErr %v", err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("parseUploadedBlobSize() = %v, want %v", got, tt.want)
}
})
}
}