Merge pull request #3900 from MichaelEischer/b2-init-timeout

Add timeout for the initial connection to B2
This commit is contained in:
Michael Eischer 2022-09-10 23:28:59 +02:00 committed by GitHub
commit 8b9778d537
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -6,6 +6,8 @@ import (
"io"
"net/http"
"path"
"sync"
"time"
"github.com/restic/restic/internal/backend"
"github.com/restic/restic/internal/backend/sema"
@ -33,11 +35,37 @@ const defaultListMaxItems = 10 * 1000
// ensure statically that *b2Backend implements restic.Backend.
var _ restic.Backend = &b2Backend{}
func newClient(ctx context.Context, cfg Config, rt http.RoundTripper) (*b2.Client, error) {
opts := []b2.ClientOption{b2.Transport(rt)}
type sniffingRoundTripper struct {
sync.Mutex
lastErr error
http.RoundTripper
}
c, err := b2.NewClient(ctx, cfg.AccountID, cfg.Key.Unwrap(), opts...)
func (s *sniffingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
res, err := s.RoundTripper.RoundTrip(req)
if err != nil {
s.Lock()
s.lastErr = err
s.Unlock()
}
return res, err
}
func newClient(ctx context.Context, cfg Config, rt http.RoundTripper) (*b2.Client, error) {
sniffer := &sniffingRoundTripper{RoundTripper: rt}
opts := []b2.ClientOption{b2.Transport(sniffer)}
// if the connection B2 fails, this can cause the client to hang
// cancel the connection after a minute to at least provide some feedback to the user
ctx, cancel := context.WithTimeout(ctx, time.Minute)
defer cancel()
c, err := b2.NewClient(ctx, cfg.AccountID, cfg.Key.Unwrap(), opts...)
if err == context.DeadlineExceeded {
if sniffer.lastErr != nil {
return nil, sniffer.lastErr
}
return nil, errors.New("connection to B2 failed")
} else if err != nil {
return nil, errors.Wrap(err, "b2.NewClient")
}
return c, nil