67 lines
1.6 KiB
Go
67 lines
1.6 KiB
Go
package http
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/debridmediamanager.com/zurg/internal/config"
|
|
"github.com/debridmediamanager.com/zurg/pkg/logutil"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type HTTPClient struct {
|
|
Client *http.Client
|
|
MaxRetries int
|
|
Backoff func(attempt int) time.Duration
|
|
CheckRespStatus func(resp *http.Response, err error) bool
|
|
BearerToken string
|
|
log *zap.SugaredLogger
|
|
config config.ConfigInterface
|
|
}
|
|
|
|
func (r *HTTPClient) Do(req *http.Request) (*http.Response, error) {
|
|
if r.config != nil && strings.Contains(req.Host, "download.real-debrid.") {
|
|
prefHost := r.config.GetRandomPreferredHost()
|
|
if host := prefHost; host != "" {
|
|
req.Host = r.config.GetRandomPreferredHost()
|
|
}
|
|
}
|
|
if r.BearerToken != "" {
|
|
req.Header.Set("Authorization", "Bearer "+r.BearerToken)
|
|
}
|
|
var resp *http.Response
|
|
var err error
|
|
for attempt := 0; attempt < r.MaxRetries; attempt++ {
|
|
resp, err = r.Client.Do(req)
|
|
if !r.CheckRespStatus(resp, err) {
|
|
return resp, err
|
|
}
|
|
time.Sleep(r.Backoff(attempt))
|
|
}
|
|
return resp, err
|
|
}
|
|
|
|
func NewHTTPClient(token string, maxRetries int, cfg config.ConfigInterface) *HTTPClient {
|
|
return &HTTPClient{
|
|
BearerToken: token,
|
|
Client: &http.Client{},
|
|
MaxRetries: maxRetries,
|
|
Backoff: func(attempt int) time.Duration {
|
|
return time.Duration(attempt) * time.Second
|
|
},
|
|
CheckRespStatus: func(resp *http.Response, err error) bool {
|
|
if err != nil {
|
|
return true
|
|
}
|
|
if resp.StatusCode == 429 {
|
|
return true
|
|
}
|
|
// no need to retry)
|
|
return false
|
|
},
|
|
log: logutil.NewLogger().Named("client"),
|
|
config: cfg,
|
|
}
|
|
}
|