/
http.go
146 lines (134 loc) · 2.82 KB
/
http.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
package sdk
import (
"compress/gzip"
"encoding/json"
"io/ioutil"
"net"
"net/url"
"os"
"syscall"
"github.com/astaxie/beego/httplib"
)
func (rc *RongCloud) do(b *httplib.BeegoHTTPRequest) (body []byte, err error) {
return rc.httpRequest(b)
}
// 需要切换域名的网络错误
func isNetError(err error) bool {
netErr, ok := err.(net.Error)
if !ok {
return false
}
// 超时
if netErr.Timeout() {
return true
}
var opErr *net.OpError
opErr, ok = netErr.(*net.OpError)
if !ok {
// url 错误
urlErr, ok := netErr.(*url.Error)
if !ok {
return false
}
opErr, ok = urlErr.Err.(*net.OpError)
if !ok {
return false
}
}
switch t := opErr.Err.(type) {
case *net.DNSError:
return true
case *os.SyscallError:
if errno, ok := t.Err.(syscall.Errno); ok {
switch errno {
case syscall.ECONNREFUSED:
return true
case syscall.ETIMEDOUT:
return true
}
}
}
return false
}
func (rc *RongCloud) httpRequest(b *httplib.BeegoHTTPRequest) (body []byte, err error) {
// 使用全局 httpClient,解决 http 打开端口过多问题
b.SetTransport(rc.globalTransport)
resp, err := b.DoRequest()
if err != nil {
if isNetError(err) {
rc.ChangeURI()
}
return nil, err
}
if resp.Body == nil {
return nil, nil
}
defer resp.Body.Close()
rc.checkStatusCode(resp)
if resp.Header.Get("Content-Encoding") == "gzip" {
reader, err := gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
body, err = ioutil.ReadAll(reader)
} else {
body, err = ioutil.ReadAll(resp.Body)
}
if err = checkHTTPResponseCode(body); err != nil {
return nil, err
}
return body, err
}
// v2 api
func (rc *RongCloud) doV2(b *httplib.BeegoHTTPRequest) (body []byte, err error) {
// 使用全局 httpClient,解决 http 打开端口过多问题
b.SetTransport(rc.globalTransport)
resp, err := b.DoRequest()
if err != nil {
if isNetError(err) {
rc.ChangeURI()
}
return nil, err
}
if resp.Body == nil {
return nil, nil
}
defer resp.Body.Close()
rc.checkStatusCode(resp)
if resp.Header.Get("Content-Encoding") == "gzip" {
reader, err := gzip.NewReader(resp.Body)
if err != nil {
return nil, err
}
body, err = ioutil.ReadAll(reader)
} else {
body, err = ioutil.ReadAll(resp.Body)
}
if err = checkHTTPResponseCodeV2(body); err != nil {
return nil, err
}
return body, err
}
func checkHTTPResponseCode(rep []byte) error {
code := codePool.Get().(CodeResult)
defer codePool.Put(code)
if err := json.Unmarshal(rep, &code); err != nil {
return err
}
if code.Code != 200 {
return code
}
return nil
}
// v2 api error
func checkHTTPResponseCodeV2(rep []byte) error {
code := codePoolV2.Get().(CodeResultV2)
defer codePoolV2.Put(code)
if err := json.Unmarshal(rep, &code); err != nil {
return err
}
if code.Code != 10000 && code.Code != 200 {
return code
}
return nil
}