func isHTTPReqErrorRetryable(err error) bool {
	if err == nil {
		return false
	}
	switch e := err.(type) {
	case *url.Error:
		switch e.Err.(type) {
		case *net.DNSError, *net.OpError, net.UnknownNetworkError:
			return true
		}
		if strings.Contains(err.Error(), "Connection closed by foreign host") {
			return true
		} else if strings.Contains(err.Error(), "net/http: TLS handshake timeout") {
			return true
		} else if strings.Contains(err.Error(), "i/o timeout") {
			return true
		} else if strings.Contains(err.Error(), "connection timed out") {
			return true
		} else if strings.Contains(err.Error(), "net/http: HTTP/1.x transport connection broken") {
			return true
		}
	}
	return false
}
isHTTPReqErrorRetryable - is http requests error retryable, such
as i/o timeout, connection broken etc..
package minio
import (
	"net"
	"net/http"
	"net/url"
	"strings"
	"time"
)
var MaxRetry = 10
const MaxJitter = 1.0
const NoJitter = 0.0
const DefaultRetryUnit = time.Second
const DefaultRetryCap = time.Second * 30
func (c Client) newRetryTimer(maxRetry int, unit time.Duration, cap time.Duration, jitter float64, doneCh chan struct{}) <-chan int {
	attemptCh := make(chan int)
	exponentialBackoffWait := func(attempt int) time.Duration {
		if jitter < NoJitter {
			jitter = NoJitter
		}
		if jitter > MaxJitter {
			jitter = MaxJitter
		}
		sleep := unit * time.Duration(1<<uint(attempt))
		if sleep > cap {
			sleep = cap
		}
		if jitter != NoJitter {
			sleep -= time.Duration(c.random.Float64() * float64(sleep) * jitter)
		}
		return sleep
	}
	go func() {
		defer close(attemptCh)
		for i := 0; i < maxRetry; i++ {
			select {
			case attemptCh <- i + 1:
			case <-doneCh:
				return
			}
			time.Sleep(exponentialBackoffWait(i))
		}
	}()
	return attemptCh
}