-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathclient.go
147 lines (131 loc) · 3.82 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package bilibili
import (
"github.com/go-resty/resty/v2"
"github.com/pkg/errors"
"github.com/tidwall/gjson"
"net/http"
"strconv"
"strings"
"time"
)
type Client struct {
cookies []*http.Cookie
cookiesString string
timeout time.Duration
logger resty.Logger
}
// New 返回一个 bilibili.Client
func New() *Client {
return &Client{timeout: 20 * time.Second}
}
var std = New()
// SetTimeout 设置http请求超时时间
func SetTimeout(timeout time.Duration) {
std.SetTimeout(timeout)
}
func (c *Client) SetTimeout(timeout time.Duration) {
c.timeout = timeout
}
// GetTimeout 获取http请求超时时间,默认20秒
func GetTimeout() time.Duration {
return std.GetTimeout()
}
func (c *Client) GetTimeout() time.Duration {
if c.timeout == 0 {
return time.Second * 20
}
return c.timeout
}
// SetLogger 设置logger
func SetLogger(logger resty.Logger) {
std.SetLogger(logger)
}
func (c *Client) SetLogger(logger resty.Logger) {
c.logger = logger
}
// GetLogger 获取logger,默认使用resty默认的logger
func GetLogger() resty.Logger {
return std.GetLogger()
}
func (c *Client) GetLogger() resty.Logger {
return c.logger
}
// GetCookiesString 获取字符串格式的cookies,方便自行存储后下次使用。配合下面的 SetCookiesString 使用。
func GetCookiesString() string {
return std.cookiesString
}
func (c *Client) GetCookiesString() string {
return c.cookiesString
}
// SetCookiesString 设置Cookies,但是是字符串格式,配合 GetCookiesString 使用。有些功能必须登录或设置Cookies后才能使用。
func SetCookiesString(cookiesString string) {
std.SetCookiesString(cookiesString)
}
func (c *Client) SetCookiesString(cookiesString string) {
c.cookiesString = cookiesString
c.cookies = (&resty.Response{RawResponse: &http.Response{Header: http.Header{
"Set-Cookie": strings.Split(cookiesString, "\n"),
}}}).Cookies()
}
// GetCookies 获取Cookies。配合下面的SetCookies使用。
func GetCookies() []*http.Cookie {
return std.GetCookies()
}
func (c *Client) GetCookies() []*http.Cookie {
return c.cookies
}
// SetCookies 设置Cookies。有些功能必须登录之后才能使用,设置Cookies可以代替登录。
func SetCookies(cookies []*http.Cookie) {
std.SetCookies(cookies)
}
func (c *Client) SetCookies(cookies []*http.Cookie) {
c.cookies = cookies
var cookieStrings []string
for _, cookie := range c.cookies {
cookieStrings = append(cookieStrings, cookie.String())
}
c.cookiesString = strings.Join(cookieStrings, "\n")
}
// 获取resty的一个request
func (c *Client) resty() *resty.Client {
client := resty.New().SetTimeout(c.GetTimeout()).SetHeader("user-agent", "go")
if c.logger != nil {
client.SetLogger(c.logger)
}
if c.cookies != nil {
client.SetCookies(c.cookies)
}
return client
}
// 根据key获取指定的cookie值
func (c *Client) getCookie(name string) string {
now := time.Now()
for _, cookie := range c.cookies {
if cookie.Name == name && now.Before(cookie.Expires) {
return cookie.Value
}
}
return ""
}
func formatError(prefix string, code int64, message ...string) error {
for _, m := range message {
if len(m) > 0 {
return errors.New(prefix + "失败,返回值:" + strconv.FormatInt(code, 10) + ",返回信息:" + m)
}
}
return errors.New(prefix + "失败,返回值:" + strconv.FormatInt(code, 10))
}
func getRespData(resp *resty.Response, prefix string) ([]byte, error) {
if resp.StatusCode() != 200 {
return nil, errors.Errorf(prefix+"失败,status code: %d", resp.StatusCode())
}
if !gjson.ValidBytes(resp.Body()) {
return nil, errors.New("json解析失败:" + resp.String())
}
res := gjson.ParseBytes(resp.Body())
code := res.Get("code").Int()
if code != 0 {
return nil, formatError(prefix, code, res.Get("message").String(), res.Get("msg").String())
}
return []byte(res.Get("data").Raw), nil
}