From c5d5f938e3b069dbf3487e64c9d567bf9910f23b Mon Sep 17 00:00:00 2001 From: Damien Mathieu Date: Fri, 10 May 2019 14:08:31 +0200 Subject: [PATCH] fast-stop ServeBlob if we're doing a HEAD request A registry pointing to ECR is having issues if we try loading the blob Signed-off-by: Damien Mathieu --- registry/client/repository.go | 14 +++++---- registry/client/repository_test.go | 48 ++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/registry/client/repository.go b/registry/client/repository.go index 8611f0fe..7a1edf78 100644 --- a/registry/client/repository.go +++ b/registry/client/repository.go @@ -672,17 +672,21 @@ func (bs *blobs) ServeBlob(ctx context.Context, w http.ResponseWriter, r *http.R return err } + w.Header().Set("Content-Length", strconv.FormatInt(desc.Size, 10)) + w.Header().Set("Content-Type", desc.MediaType) + w.Header().Set("Docker-Content-Digest", dgst.String()) + w.Header().Set("Etag", dgst.String()) + + if r.Method == http.MethodHead { + return nil + } + blob, err := bs.Open(ctx, dgst) if err != nil { return err } defer blob.Close() - w.Header().Set("Content-Length", strconv.FormatInt(desc.Size, 10)) - w.Header().Set("Content-Type", desc.MediaType) - w.Header().Set("Docker-Content-Digest", dgst.String()) - w.Header().Set("Etag", dgst.String()) - _, err = io.CopyN(w, blob, desc.Size) return err } diff --git a/registry/client/repository_test.go b/registry/client/repository_test.go index 0622c633..51dbb4d1 100644 --- a/registry/client/repository_test.go +++ b/registry/client/repository_test.go @@ -149,7 +149,55 @@ func TestBlobServeBlob(t *testing.T) { t.Errorf("Unexpected %s. Got %s, expected %s", h.Name, resp.Header().Get(h.Name), h.Value) } } +} +func TestBlobServeBlobHEAD(t *testing.T) { + dgst, blob := newRandomBlob(1024) + var m testutil.RequestResponseMap + addTestFetch("test.example.com/repo1", dgst, blob, &m) + + e, c := testServer(m) + defer c() + + ctx := context.Background() + repo, _ := reference.WithName("test.example.com/repo1") + r, err := NewRepository(repo, e, nil) + if err != nil { + t.Fatal(err) + } + l := r.Blobs(ctx) + + resp := httptest.NewRecorder() + req := httptest.NewRequest("HEAD", "/", nil) + + err = l.ServeBlob(ctx, resp, req, dgst) + if err != nil { + t.Errorf("Error serving blob: %s", err.Error()) + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + t.Errorf("Error reading response body: %s", err.Error()) + } + if string(body) != "" { + t.Errorf("Unexpected response body. Got %q, expected %q", string(body), "") + } + + expectedHeaders := []struct { + Name string + Value string + }{ + {Name: "Content-Length", Value: "1024"}, + {Name: "Content-Type", Value: "application/octet-stream"}, + {Name: "Docker-Content-Digest", Value: dgst.String()}, + {Name: "Etag", Value: dgst.String()}, + } + + for _, h := range expectedHeaders { + if resp.Header().Get(h.Name) != h.Value { + t.Errorf("Unexpected %s. Got %s, expected %s", h.Name, resp.Header().Get(h.Name), h.Value) + } + } } func TestBlobDelete(t *testing.T) {