Include headers when serving blob through proxy (#4273)
This commit is contained in:
commit
2c6b6482fc
2 changed files with 20 additions and 12 deletions
|
@ -33,22 +33,20 @@ var inflight = make(map[digest.Digest]struct{})
|
||||||
// mu protects inflight
|
// mu protects inflight
|
||||||
var mu sync.Mutex
|
var mu sync.Mutex
|
||||||
|
|
||||||
func setResponseHeaders(w http.ResponseWriter, length int64, mediaType string, digest digest.Digest) {
|
func setResponseHeaders(h http.Header, length int64, mediaType string, digest digest.Digest) {
|
||||||
w.Header().Set("Content-Length", strconv.FormatInt(length, 10))
|
h.Set("Content-Length", strconv.FormatInt(length, 10))
|
||||||
w.Header().Set("Content-Type", mediaType)
|
h.Set("Content-Type", mediaType)
|
||||||
w.Header().Set("Docker-Content-Digest", digest.String())
|
h.Set("Docker-Content-Digest", digest.String())
|
||||||
w.Header().Set("Etag", digest.String())
|
h.Set("Etag", digest.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pbs *proxyBlobStore) copyContent(ctx context.Context, dgst digest.Digest, writer io.Writer) (distribution.Descriptor, error) {
|
func (pbs *proxyBlobStore) copyContent(ctx context.Context, dgst digest.Digest, writer io.Writer, h http.Header) (distribution.Descriptor, error) {
|
||||||
desc, err := pbs.remoteStore.Stat(ctx, dgst)
|
desc, err := pbs.remoteStore.Stat(ctx, dgst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return distribution.Descriptor{}, err
|
return distribution.Descriptor{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if w, ok := writer.(http.ResponseWriter); ok {
|
setResponseHeaders(h, desc.Size, desc.MediaType, dgst)
|
||||||
setResponseHeaders(w, desc.Size, desc.MediaType, dgst)
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteReader, err := pbs.remoteStore.Open(ctx, dgst)
|
remoteReader, err := pbs.remoteStore.Open(ctx, dgst)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -102,7 +100,7 @@ func (pbs *proxyBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter,
|
||||||
// Will return the blob from the remote store directly.
|
// Will return the blob from the remote store directly.
|
||||||
// TODO Maybe we could reuse the these blobs are serving remotely and caching locally.
|
// TODO Maybe we could reuse the these blobs are serving remotely and caching locally.
|
||||||
mu.Unlock()
|
mu.Unlock()
|
||||||
_, err := pbs.copyContent(ctx, dgst, w)
|
_, err := pbs.copyContent(ctx, dgst, w, w.Header())
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
inflight[dgst] = struct{}{}
|
inflight[dgst] = struct{}{}
|
||||||
|
@ -122,7 +120,7 @@ func (pbs *proxyBlobStore) ServeBlob(ctx context.Context, w http.ResponseWriter,
|
||||||
// Serving client and storing locally over same fetching request.
|
// Serving client and storing locally over same fetching request.
|
||||||
// This can prevent a redundant blob fetching.
|
// This can prevent a redundant blob fetching.
|
||||||
multiWriter := io.MultiWriter(w, bw)
|
multiWriter := io.MultiWriter(w, bw)
|
||||||
desc, err := pbs.copyContent(ctx, dgst, multiWriter)
|
desc, err := pbs.copyContent(ctx, dgst, multiWriter, w.Header())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -448,12 +448,22 @@ func testProxyStoreServe(t *testing.T, te *testEnv, numClients int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bodyBytes := w.Body.Bytes()
|
resp := w.Result()
|
||||||
|
bodyBytes, err := io.ReadAll(resp.Body)
|
||||||
|
resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
localDigest := digest.FromBytes(bodyBytes)
|
localDigest := digest.FromBytes(bodyBytes)
|
||||||
if localDigest != remoteBlob.Digest {
|
if localDigest != remoteBlob.Digest {
|
||||||
t.Errorf("Mismatching blob fetch from proxy")
|
t.Errorf("Mismatching blob fetch from proxy")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if resp.Header.Get("Docker-Content-Digest") != localDigest.String() {
|
||||||
|
t.Errorf("Mismatching digest in response header")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
desc, err := te.store.localStore.Stat(te.ctx, remoteBlob.Digest)
|
desc, err := te.store.localStore.Stat(te.ctx, remoteBlob.Digest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in a new issue