Skip to content

Commit

Permalink
util/resolver: Make httpFallback concurrent safe
Browse files Browse the repository at this point in the history
The httpFallback mutates the `host` field, which needs a synchronization
when the same httpFallback is used by multiple goroutines.
This is happens with containerd push which uses `Dispatch` to
walk the image recursively to push every blob.

Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
(cherry picked from commit 0285950)
  • Loading branch information
vvoland authored and tonistiigi committed Jun 18, 2024
1 parent 49dd5f4 commit 2bf5cbf
Showing 1 changed file with 16 additions and 5 deletions.
21 changes: 16 additions & 5 deletions util/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"path/filepath"
"runtime"
"strings"
"sync"
"syscall"
"time"

Expand Down Expand Up @@ -213,13 +214,18 @@ func newDefaultTransport() *http.Transport {
}

type httpFallback struct {
super http.RoundTripper
host string
super http.RoundTripper
host string
hostMut sync.Mutex
}

func (f *httpFallback) RoundTrip(r *http.Request) (*http.Response, error) {
// only fall back if the same host had previously fell back
if f.host != r.URL.Host {
f.hostMut.Lock()
// Skip the HTTPS call only if the same host had previously fell back
tryHTTPSFirst := f.host != r.URL.Host
f.hostMut.Unlock()

if tryHTTPSFirst {
resp, err := f.super.RoundTrip(r)
if !isTLSError(err) && !isPortError(err, r.URL.Host) {
return resp, err
Expand All @@ -232,8 +238,13 @@ func (f *httpFallback) RoundTrip(r *http.Request) (*http.Response, error) {
plainHTTPRequest := *r
plainHTTPRequest.URL = &plainHTTPUrl

if f.host != r.URL.Host {
// We tried HTTPS first but it failed.
// Mark the host so we don't try HTTPS for this host next time
// and refresh the request body.
if tryHTTPSFirst {
f.hostMut.Lock()
f.host = r.URL.Host
f.hostMut.Unlock()

// update body on the second attempt
if r.Body != nil && r.GetBody != nil {
Expand Down

0 comments on commit 2bf5cbf

Please sign in to comment.