136 lines
2.4 KiB
Go
136 lines
2.4 KiB
Go
|
package qbittorrent
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"net/http"
|
||
|
"net/http/cookiejar"
|
||
|
"net/url"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type responseResult struct {
|
||
|
code int
|
||
|
body []byte
|
||
|
cookies []*http.Cookie
|
||
|
}
|
||
|
|
||
|
type requestData struct {
|
||
|
method string
|
||
|
url string
|
||
|
contentType string
|
||
|
body io.Reader
|
||
|
}
|
||
|
|
||
|
var _ Client = (*client)(nil)
|
||
|
|
||
|
type client struct {
|
||
|
config *Config
|
||
|
clientPool *clientPool
|
||
|
cookieJar *cookiejar.Jar
|
||
|
}
|
||
|
|
||
|
func (c *client) Authentication() Authentication {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Application() Application {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Log() Log {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Sync() Sync {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Transfer() Transfer {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Torrent() Torrent {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) Search() Search {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
func (c *client) RSS() RSS {
|
||
|
return c
|
||
|
}
|
||
|
|
||
|
// doRequest send request
|
||
|
func (c *client) doRequest(ctx context.Context, data *requestData) (*responseResult, error) {
|
||
|
if data.method == "" {
|
||
|
data.method = "GET"
|
||
|
}
|
||
|
if data.contentType == "" {
|
||
|
data.contentType = ContentTypeFormUrlEncoded
|
||
|
}
|
||
|
request, err := http.NewRequestWithContext(ctx, data.method, data.url, data.body)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
request.Header.Set("Content-Type", data.contentType)
|
||
|
for key, value := range c.config.CustomHeaders {
|
||
|
request.Header.Set(key, value)
|
||
|
}
|
||
|
hc := c.clientPool.GetClient()
|
||
|
defer c.clientPool.ReleaseClient(hc)
|
||
|
if c.cookieJar != nil {
|
||
|
hc.Jar = c.cookieJar
|
||
|
}
|
||
|
|
||
|
resp, err := hc.Do(request)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
readAll, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
return &responseResult{code: resp.StatusCode, body: readAll, cookies: resp.Cookies()}, nil
|
||
|
}
|
||
|
|
||
|
func (c *client) cookies() (string, error) {
|
||
|
if c.cookieJar == nil {
|
||
|
return "", ErrNotLogin
|
||
|
}
|
||
|
u, err := url.Parse(c.config.Address)
|
||
|
if err != nil {
|
||
|
return "", err
|
||
|
}
|
||
|
cookies := c.cookieJar.Cookies(u)
|
||
|
if len(cookies) == 0 {
|
||
|
return "", ErrNotLogin
|
||
|
}
|
||
|
var builder strings.Builder
|
||
|
for _, cookie := range cookies {
|
||
|
builder.WriteString(fmt.Sprintf("%s=%s; ", cookie.Name, cookie.Value))
|
||
|
}
|
||
|
|
||
|
return builder.String(), nil
|
||
|
}
|
||
|
|
||
|
func (c *client) refreshCookie() {
|
||
|
ctx := context.Background()
|
||
|
if c.config.RefreshIntervals == 0 {
|
||
|
c.config.RefreshIntervals = time.Hour
|
||
|
}
|
||
|
var ticker = time.NewTicker(c.config.RefreshIntervals)
|
||
|
for range ticker.C {
|
||
|
if err := c.Authentication().Logout(ctx); err != nil {
|
||
|
// todo
|
||
|
}
|
||
|
}
|
||
|
}
|