main.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. //go:build windows
  2. package yu_proxy_pool
  3. import (
  4. yu_curl "gogs.qqck.cn/s/tools/curl"
  5. yu_proxy "gogs.qqck.cn/s/tools/proxy"
  6. yu_strconv "gogs.qqck.cn/s/tools/strconv"
  7. "strings"
  8. "sync"
  9. "time"
  10. )
  11. // Pool 代理池
  12. type Pool struct {
  13. // 并发锁
  14. lock sync.Mutex
  15. // 代理池
  16. list []*pool_item
  17. // 代理API
  18. // 提取链接或直连地址
  19. url string
  20. // 0:返回代理列表,1:直连地址,默认为0
  21. url_type byte
  22. // 代理有效时长,默认为30秒,单位:秒
  23. valid_time int64
  24. // 代理池内有效时间低于该值就视为无效代理,默认为10秒,单位:秒
  25. failure_time int64
  26. // 0:http/https,1:socks5
  27. _type byte
  28. // 认证账号密码,如果代理需要身份认证的情况下填写
  29. user, pass string
  30. domain bool
  31. // 访问代理API的提取最少间隔,默认不限制
  32. request_space int64
  33. // 最后调用时间,单位:秒
  34. time_last int64
  35. // 单个 IP 最多使用次数,默认为:1
  36. get_max int
  37. // 已提取计数
  38. get_count int
  39. response string // 最后提取信息
  40. }
  41. type pool_item struct {
  42. *yu_proxy.Info
  43. i int // 已使用计数
  44. }
  45. func New() (t *Pool) {
  46. t = &Pool{}
  47. t.list = make([]*pool_item, 0)
  48. t.SetUrlList().SetValidTime(30).SetFailureTime(10).SetHttp().SetDomain(true).SetGetMax(1)
  49. return
  50. }
  51. // -----------------------------------------------------------------------------------------------------API
  52. // SetUrl 设置提取代理api链接
  53. func (t *Pool) SetUrl(v string) *Pool {
  54. t.lock.Lock()
  55. defer t.lock.Unlock()
  56. t.url = v
  57. return t
  58. }
  59. // GetUrl 获取提取代理api链接
  60. func (t *Pool) GetUrl() string {
  61. t.lock.Lock()
  62. defer t.lock.Unlock()
  63. return t.url
  64. }
  65. // SetUrlList 设置提取代理 api 链接 返回类型为:代理列表
  66. func (t *Pool) SetUrlList() *Pool {
  67. t.lock.Lock()
  68. defer t.lock.Unlock()
  69. t.url_type = 0
  70. return t
  71. }
  72. // SetUrlTunnel 设置提取代理 api 链接 返回类型为:隧道代理,直连地址
  73. func (t *Pool) SetUrlTunnel() *Pool {
  74. t.lock.Lock()
  75. defer t.lock.Unlock()
  76. t.url_type = 1
  77. return t
  78. }
  79. // SetValidTime 设置代理有效时长,默认为30秒,单位:秒
  80. func (t *Pool) SetValidTime(v int64) *Pool {
  81. t.lock.Lock()
  82. defer t.lock.Unlock()
  83. if v < 1 {
  84. v = 30
  85. }
  86. t.valid_time = v
  87. return t
  88. }
  89. // GetValidTime 获取代理有效时长,单位:秒
  90. func (t *Pool) GetValidTime() int64 {
  91. t.lock.Lock()
  92. defer t.lock.Unlock()
  93. return t.valid_time
  94. }
  95. // SetFailureTime 设置代理池内有效时间低于该值就视为无效代理,默认为10秒,单位:秒
  96. func (t *Pool) SetFailureTime(v int64) *Pool {
  97. t.lock.Lock()
  98. defer t.lock.Unlock()
  99. if v < 1 {
  100. v = 10
  101. }
  102. t.failure_time = v
  103. return t
  104. }
  105. // GetFailureTime 获取代理池内有效时间低于该值就视为无效代理,单位:秒
  106. func (t *Pool) GetFailureTime() int64 {
  107. t.lock.Lock()
  108. defer t.lock.Unlock()
  109. return t.failure_time
  110. }
  111. // SetHttp 设置代理类型为:http/https
  112. func (t *Pool) SetHttp() *Pool {
  113. t.lock.Lock()
  114. defer t.lock.Unlock()
  115. t._type = 0
  116. return t
  117. }
  118. // SetSocks5 设置代理类型为:socks5
  119. func (t *Pool) SetSocks5() *Pool {
  120. t.lock.Lock()
  121. defer t.lock.Unlock()
  122. t._type = 1
  123. return t
  124. }
  125. // SetUser 设置代理认证账号,如果代理需要身份认证的情况下填写
  126. func (t *Pool) SetUser(v string) *Pool {
  127. t.lock.Lock()
  128. defer t.lock.Unlock()
  129. t.user = v
  130. return t
  131. }
  132. // GetUser 获取代理认证账号
  133. func (t *Pool) GetUser() string {
  134. t.lock.Lock()
  135. defer t.lock.Unlock()
  136. return t.user
  137. }
  138. // SetPass 设置代理认证密码,如果代理需要身份认证的情况下填写
  139. func (t *Pool) SetPass(v string) *Pool {
  140. t.lock.Lock()
  141. defer t.lock.Unlock()
  142. t.pass = v
  143. return t
  144. }
  145. // GetPass 获取代理认证密码
  146. func (t *Pool) GetPass() string {
  147. t.lock.Lock()
  148. defer t.lock.Unlock()
  149. return t.pass
  150. }
  151. // SetDomain
  152. //
  153. // @Description: 设置是否由代理解析域名,默认:true
  154. func (t *Pool) SetDomain(value bool) *Pool {
  155. t.domain = value
  156. return t
  157. }
  158. // SetRequestSpace 设置访问代理API的提取最少间隔,默认不限制
  159. func (t *Pool) SetRequestSpace(v int64) *Pool {
  160. t.lock.Lock()
  161. defer t.lock.Unlock()
  162. t.request_space = v
  163. return t
  164. }
  165. // GetRequestSpace 获取访问代理API的提取最少间隔
  166. func (t *Pool) GetRequestSpace() int64 {
  167. t.lock.Lock()
  168. defer t.lock.Unlock()
  169. return t.request_space
  170. }
  171. // SetGetMax 单个 IP 最多使用次数,默认为:1
  172. func (t *Pool) SetGetMax(n int) *Pool {
  173. t.lock.Lock()
  174. defer t.lock.Unlock()
  175. t.get_max = n
  176. return t
  177. }
  178. // Size 取当前IP池内剩余IP数
  179. func (t *Pool) Size() int {
  180. t.lock.Lock()
  181. defer t.lock.Unlock()
  182. return len(t.list)
  183. }
  184. // Clear 清空代理池提取的代理信息
  185. func (t *Pool) Clear() {
  186. t.lock.Lock()
  187. defer t.lock.Unlock()
  188. t.list = make([]*pool_item, 0)
  189. }
  190. // -----------------------------------------------------------------------------------------------------Get
  191. // Get 计次提取
  192. func (t *Pool) Get() *yu_proxy.Info {
  193. t.lock.Lock()
  194. defer t.lock.Unlock()
  195. if t.get_max < 1 {
  196. return nil
  197. }
  198. var j_get bool
  199. _get:
  200. for len(t.list) > 0 {
  201. if !t.list[0].IsValid() {
  202. t.list = t.list[1:]
  203. continue
  204. }
  205. if t.list[0].i >= t.get_max {
  206. t.list = t.list[1:]
  207. continue
  208. }
  209. t.list[0].i++
  210. return t.list[0].Copy()
  211. }
  212. if j_get = !j_get; j_get && t.request_url() {
  213. goto _get
  214. }
  215. return nil
  216. }
  217. // GetCheck 计次提取并使用校验函数校验是否可用(只在从列表提取新的IP的时候才会校验)
  218. func (t *Pool) GetCheck(on func(*yu_proxy.Info) bool) *yu_proxy.Info {
  219. if on == nil {
  220. return t.Get()
  221. }
  222. var j_info *pool_item
  223. j_check := false
  224. t.lock.Lock()
  225. if t.get_max > 0 {
  226. var j_get bool
  227. _get:
  228. for len(t.list) > 0 {
  229. if !t.list[0].IsValid() {
  230. t.list = t.list[1:]
  231. continue
  232. }
  233. if t.list[0].i >= t.get_max {
  234. t.list = t.list[1:]
  235. continue
  236. }
  237. if t.list[0].i == 0 {
  238. j_info, j_check, t.list = t.list[0], true, t.list[1:]
  239. break
  240. }
  241. t.list[0].i++
  242. j_info = t.list[0]
  243. break
  244. }
  245. if j_get = !j_get; j_info == nil && j_get && t.request_url() {
  246. goto _get
  247. }
  248. }
  249. t.lock.Unlock()
  250. if j_info == nil {
  251. return nil
  252. }
  253. if !j_check {
  254. return j_info.Copy()
  255. }
  256. if !on(j_info.Info) {
  257. return nil
  258. }
  259. j_info.i++
  260. t.lock.Lock()
  261. t.list = append(t.list, nil)
  262. for j_i := len(t.list) - 1; j_i > 0; j_i-- {
  263. t.list[j_i] = t.list[j_i-1]
  264. }
  265. t.list[0] = j_info
  266. t.lock.Unlock()
  267. return j_info.Copy()
  268. }
  269. // GetCheckEx 计次提取并使用校验函数校验是否可用(不管是不是从列表提取新的IP都进行校验)
  270. func (t *Pool) GetCheckEx(on func(*yu_proxy.Info) bool) *yu_proxy.Info {
  271. if on == nil {
  272. return t.Get()
  273. }
  274. var j_info *pool_item
  275. t.lock.Lock()
  276. if t.get_max > 0 {
  277. var j_get bool
  278. _get:
  279. for len(t.list) > 0 {
  280. if !t.list[0].IsValid() {
  281. t.list = t.list[1:]
  282. continue
  283. }
  284. if t.list[0].i >= t.get_max {
  285. t.list = t.list[1:]
  286. continue
  287. }
  288. j_info = t.list[0]
  289. break
  290. }
  291. if j_get = !j_get; j_info == nil && j_get && t.request_url() {
  292. goto _get
  293. }
  294. }
  295. t.lock.Unlock()
  296. if j_info == nil {
  297. return nil
  298. }
  299. if !on(j_info.Info) {
  300. return nil
  301. }
  302. j_info.i++
  303. t.lock.Lock()
  304. t.list = append(t.list, nil)
  305. for j_i := len(t.list) - 1; j_i > 0; j_i-- {
  306. t.list[j_i] = t.list[j_i-1]
  307. }
  308. t.list[0] = j_info
  309. t.lock.Unlock()
  310. return j_info.Copy()
  311. }
  312. func (t *Pool) GetResponse() string {
  313. return t.response
  314. }
  315. func (t *Pool) request_url() bool {
  316. if t.url_type == 0 {
  317. j_time := time.Now().Unix()
  318. if j_time-t.time_last < t.request_space {
  319. return false
  320. }
  321. j_curl := yu_curl.NewRequest().SetSslVerifyHost(yu_curl.SSLVERSION_DEFAULT).SetSslVerifyPeer(false).SetTimeout(1000 * 30)
  322. defer j_curl.Close()
  323. if j_curl.Get(t.url).RespErr() != nil || j_curl.RespStatusCode() != 200 {
  324. return false
  325. }
  326. t.response = j_curl.RespBodyS()
  327. j_proxy_list := []string(nil)
  328. if strings.Index(t.response, "\r\n") > -1 {
  329. j_proxy_list = strings.Split(t.response, "\r\n")
  330. } else if strings.Index(t.response, "\\r\\n") > -1 {
  331. j_proxy_list = strings.Split(t.response, "\\r\\n")
  332. } else if strings.Index(t.response, "\r") > -1 {
  333. j_proxy_list = strings.Split(t.response, "\r")
  334. } else if strings.Index(t.response, "\\r") > -1 {
  335. j_proxy_list = strings.Split(t.response, "\\r")
  336. } else if strings.Index(t.response, "\n") > -1 {
  337. j_proxy_list = strings.Split(t.response, "\n")
  338. } else if strings.Index(t.response, "\\n") > -1 {
  339. j_proxy_list = strings.Split(t.response, "\\n")
  340. } else if strings.Index(t.response, " ") > -1 {
  341. j_proxy_list = strings.Split(t.response, " ")
  342. } else if strings.Index(t.response, "<br/>") > -1 {
  343. j_proxy_list = strings.Split(t.response, "<br/>")
  344. } else {
  345. j_proxy_list = append(j_proxy_list, t.response)
  346. }
  347. t.time_last, j_time = j_time, j_time+t.valid_time-t.failure_time
  348. for j_i := 0; j_i < len(j_proxy_list); j_i++ {
  349. j_proxy_info := &pool_item{Info: yu_proxy.NewInfo().SetAuthorization(t.user, t.pass)}
  350. if strings.Index(j_proxy_list[j_i], " ") > -1 {
  351. if j_ip_port := strings.Split(j_proxy_list[j_i], " "); len(j_ip_port) == 3 {
  352. j_proxy_list[j_i] = j_ip_port[0]
  353. j_proxy_info.User, j_proxy_info.Pass = j_ip_port[1], j_ip_port[2]
  354. }
  355. }
  356. if strings.Count(j_proxy_list[j_i], ".") == 3 && strings.Count(j_proxy_list[j_i], ":") == 1 {
  357. j_addr := strings.Split(j_proxy_list[j_i], ":")
  358. j_proxy_info.Host, j_proxy_info.Port, j_proxy_info.Type, j_proxy_info.Timeout, j_proxy_info.Domain = j_addr[0], yu_strconv.ParseInt(j_addr[1]), t._type, j_time, t.domain
  359. t.list = append(t.list, j_proxy_info)
  360. }
  361. }
  362. return len(t.list) > 0
  363. } else if t.url_type == 1 {
  364. j_len := 100
  365. t.list = make([]*pool_item, j_len)
  366. for j_num := 0; j_num < j_len; j_num++ {
  367. t.list[j_num] = &pool_item{}
  368. t.list[j_num].Info = yu_proxy.NewInfo()
  369. t.list[j_num].Host = t.url
  370. t.list[j_num].User = t.user
  371. t.list[j_num].Pass = t.pass
  372. t.list[j_num].Type = t._type
  373. t.list[j_num].Timeout = -1
  374. t.list[j_num].Domain = t.domain
  375. }
  376. return true
  377. }
  378. return false
  379. }