Skip to content

Commit

Permalink
Merge pull request #1159 from erydo/fix-etag
Browse files Browse the repository at this point in the history
http: Handle missing but unambiguous ETags in response
  • Loading branch information
tiborvass authored Sep 5, 2019
2 parents 0639e6f + 6ff0868 commit 7886d6b
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions source/http/httpsource.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ func (hs *httpSourceHandler) CacheKey(ctx context.Context, index int) (string, b
req = req.WithContext(ctx)
m := map[string]*metadata.StorageItem{}

// If we request a single ETag in 'If-None-Match', some servers omit the
// unambiguous ETag in their response.
// See: https://github.com/moby/buildkit/issues/905
var onlyETag string

if len(sis) > 0 {
for _, si := range sis {
// if metaDigest := getMetaDigest(si); metaDigest == hs.formatCacheKey("") {
Expand All @@ -160,6 +165,10 @@ func (hs *httpSourceHandler) CacheKey(ctx context.Context, index int) (string, b
etags = append(etags, t)
}
req.Header.Add("If-None-Match", strings.Join(etags, ", "))

if len(etags) == 1 {
onlyETag = etags[0]
}
}
}

Expand All @@ -172,6 +181,12 @@ func (hs *httpSourceHandler) CacheKey(ctx context.Context, index int) (string, b
if err == nil {
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotModified {
respETag := resp.Header.Get("ETag")

// If a 304 is returned without an ETag and we had only sent one ETag,
// the response refers to the ETag we asked about.
if respETag == "" && onlyETag != "" && resp.StatusCode == http.StatusNotModified {
respETag = onlyETag
}
si, ok := m[respETag]
if ok {
hs.refID = si.ID()
Expand All @@ -197,6 +212,13 @@ func (hs *httpSourceHandler) CacheKey(ctx context.Context, index int) (string, b
}
if resp.StatusCode == http.StatusNotModified {
respETag := resp.Header.Get("ETag")
if respETag == "" && onlyETag != "" {
respETag = onlyETag

// Set the missing ETag header on the response so that it's available
// to .save()
resp.Header.Set("ETag", onlyETag)
}
si, ok := m[respETag]
if !ok {
return "", false, errors.Errorf("invalid not-modified ETag: %v", respETag)
Expand Down

0 comments on commit 7886d6b

Please sign in to comment.