123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- //go:build windows
- package yu_proxy_pool
- import (
- yu_curl "gogs.qqck.cn/s/tools/curl"
- yu_proxy "gogs.qqck.cn/s/tools/proxy"
- yu_strconv "gogs.qqck.cn/s/tools/strconv"
- "strings"
- "sync"
- "time"
- )
- // Pool 代理池
- type Pool struct {
- // 并发锁
- lock sync.Mutex
- // 代理池
- list []*pool_item
- // 代理API
- // 提取链接或直连地址
- url string
- // 0:返回代理列表,1:直连地址,默认为0
- url_type byte
- // 代理有效时长,默认为30秒,单位:秒
- valid_time int64
- // 代理池内有效时间低于该值就视为无效代理,默认为10秒,单位:秒
- failure_time int64
- // 0:http/https,1:socks5
- _type byte
- // 认证账号密码,如果代理需要身份认证的情况下填写
- user, pass string
- domain bool
- // 访问代理API的提取最少间隔,默认不限制
- request_space int64
- // 最后调用时间,单位:秒
- time_last int64
- // 单个 IP 最多使用次数,默认为:1
- get_max int
- // 已提取计数
- get_count int
- response string // 最后提取信息
- }
- type pool_item struct {
- *yu_proxy.Info
- i int // 已使用计数
- }
- func New() (t *Pool) {
- t = &Pool{}
- t.list = make([]*pool_item, 0)
- t.SetUrlList().SetValidTime(30).SetFailureTime(10).SetHttp().SetDomain(true).SetGetMax(1)
- return
- }
- // -----------------------------------------------------------------------------------------------------API
- // SetUrl 设置提取代理api链接
- func (t *Pool) SetUrl(v string) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.url = v
- return t
- }
- // GetUrl 获取提取代理api链接
- func (t *Pool) GetUrl() string {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.url
- }
- // SetUrlList 设置提取代理 api 链接 返回类型为:代理列表
- func (t *Pool) SetUrlList() *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.url_type = 0
- return t
- }
- // SetUrlTunnel 设置提取代理 api 链接 返回类型为:隧道代理,直连地址
- func (t *Pool) SetUrlTunnel() *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.url_type = 1
- return t
- }
- // SetValidTime 设置代理有效时长,默认为30秒,单位:秒
- func (t *Pool) SetValidTime(v int64) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- if v < 1 {
- v = 30
- }
- t.valid_time = v
- return t
- }
- // GetValidTime 获取代理有效时长,单位:秒
- func (t *Pool) GetValidTime() int64 {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.valid_time
- }
- // SetFailureTime 设置代理池内有效时间低于该值就视为无效代理,默认为10秒,单位:秒
- func (t *Pool) SetFailureTime(v int64) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- if v < 1 {
- v = 10
- }
- t.failure_time = v
- return t
- }
- // GetFailureTime 获取代理池内有效时间低于该值就视为无效代理,单位:秒
- func (t *Pool) GetFailureTime() int64 {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.failure_time
- }
- // SetHttp 设置代理类型为:http/https
- func (t *Pool) SetHttp() *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t._type = 0
- return t
- }
- // SetSocks5 设置代理类型为:socks5
- func (t *Pool) SetSocks5() *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t._type = 1
- return t
- }
- // SetUser 设置代理认证账号,如果代理需要身份认证的情况下填写
- func (t *Pool) SetUser(v string) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.user = v
- return t
- }
- // GetUser 获取代理认证账号
- func (t *Pool) GetUser() string {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.user
- }
- // SetPass 设置代理认证密码,如果代理需要身份认证的情况下填写
- func (t *Pool) SetPass(v string) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.pass = v
- return t
- }
- // GetPass 获取代理认证密码
- func (t *Pool) GetPass() string {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.pass
- }
- // SetDomain
- //
- // @Description: 设置是否由代理解析域名,默认:true
- func (t *Pool) SetDomain(value bool) *Pool {
- t.domain = value
- return t
- }
- // SetRequestSpace 设置访问代理API的提取最少间隔,默认不限制
- func (t *Pool) SetRequestSpace(v int64) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.request_space = v
- return t
- }
- // GetRequestSpace 获取访问代理API的提取最少间隔
- func (t *Pool) GetRequestSpace() int64 {
- t.lock.Lock()
- defer t.lock.Unlock()
- return t.request_space
- }
- // SetGetMax 单个 IP 最多使用次数,默认为:1
- func (t *Pool) SetGetMax(n int) *Pool {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.get_max = n
- return t
- }
- // Size 取当前IP池内剩余IP数
- func (t *Pool) Size() int {
- t.lock.Lock()
- defer t.lock.Unlock()
- return len(t.list)
- }
- // Clear 清空代理池提取的代理信息
- func (t *Pool) Clear() {
- t.lock.Lock()
- defer t.lock.Unlock()
- t.list = make([]*pool_item, 0)
- }
- // -----------------------------------------------------------------------------------------------------Get
- // Get 计次提取
- func (t *Pool) Get() *yu_proxy.Info {
- t.lock.Lock()
- defer t.lock.Unlock()
- if t.get_max < 1 {
- return nil
- }
- var j_get bool
- _get:
- for len(t.list) > 0 {
- if !t.list[0].IsValid() {
- t.list = t.list[1:]
- continue
- }
- if t.list[0].i >= t.get_max {
- t.list = t.list[1:]
- continue
- }
- t.list[0].i++
- return t.list[0].Copy()
- }
- if j_get = !j_get; j_get && t.request_url() {
- goto _get
- }
- return nil
- }
- // GetCheck 计次提取并使用校验函数校验是否可用(只在从列表提取新的IP的时候才会校验)
- func (t *Pool) GetCheck(on func(*yu_proxy.Info) bool) *yu_proxy.Info {
- if on == nil {
- return t.Get()
- }
- var j_info *pool_item
- j_check := false
- t.lock.Lock()
- if t.get_max > 0 {
- var j_get bool
- _get:
- for len(t.list) > 0 {
- if !t.list[0].IsValid() {
- t.list = t.list[1:]
- continue
- }
- if t.list[0].i >= t.get_max {
- t.list = t.list[1:]
- continue
- }
- if t.list[0].i == 0 {
- j_info, j_check, t.list = t.list[0], true, t.list[1:]
- break
- }
- t.list[0].i++
- j_info = t.list[0]
- break
- }
- if j_get = !j_get; j_info == nil && j_get && t.request_url() {
- goto _get
- }
- }
- t.lock.Unlock()
- if j_info == nil {
- return nil
- }
- if !j_check {
- return j_info.Copy()
- }
- if !on(j_info.Info) {
- return nil
- }
- j_info.i++
- t.lock.Lock()
- t.list = append(t.list, nil)
- for j_i := len(t.list) - 1; j_i > 0; j_i-- {
- t.list[j_i] = t.list[j_i-1]
- }
- t.list[0] = j_info
- t.lock.Unlock()
- return j_info.Copy()
- }
- // GetCheckEx 计次提取并使用校验函数校验是否可用(不管是不是从列表提取新的IP都进行校验)
- func (t *Pool) GetCheckEx(on func(*yu_proxy.Info) bool) *yu_proxy.Info {
- if on == nil {
- return t.Get()
- }
- var j_info *pool_item
- t.lock.Lock()
- if t.get_max > 0 {
- var j_get bool
- _get:
- for len(t.list) > 0 {
- if !t.list[0].IsValid() {
- t.list = t.list[1:]
- continue
- }
- if t.list[0].i >= t.get_max {
- t.list = t.list[1:]
- continue
- }
- j_info = t.list[0]
- break
- }
- if j_get = !j_get; j_info == nil && j_get && t.request_url() {
- goto _get
- }
- }
- t.lock.Unlock()
- if j_info == nil {
- return nil
- }
- if !on(j_info.Info) {
- return nil
- }
- j_info.i++
- t.lock.Lock()
- t.list = append(t.list, nil)
- for j_i := len(t.list) - 1; j_i > 0; j_i-- {
- t.list[j_i] = t.list[j_i-1]
- }
- t.list[0] = j_info
- t.lock.Unlock()
- return j_info.Copy()
- }
- func (t *Pool) GetResponse() string {
- return t.response
- }
- func (t *Pool) request_url() bool {
- if t.url_type == 0 {
- j_time := time.Now().Unix()
- if j_time-t.time_last < t.request_space {
- return false
- }
- j_curl := yu_curl.NewRequest().SetSslVerifyHost(yu_curl.SSLVERSION_DEFAULT).SetSslVerifyPeer(false).SetTimeout(1000 * 30)
- defer j_curl.Close()
- if j_curl.Get(t.url).RespErr() != nil || j_curl.RespStatusCode() != 200 {
- return false
- }
- t.response = j_curl.RespBodyS()
- j_proxy_list := []string(nil)
- if strings.Index(t.response, "\r\n") > -1 {
- j_proxy_list = strings.Split(t.response, "\r\n")
- } else if strings.Index(t.response, "\\r\\n") > -1 {
- j_proxy_list = strings.Split(t.response, "\\r\\n")
- } else if strings.Index(t.response, "\r") > -1 {
- j_proxy_list = strings.Split(t.response, "\r")
- } else if strings.Index(t.response, "\\r") > -1 {
- j_proxy_list = strings.Split(t.response, "\\r")
- } else if strings.Index(t.response, "\n") > -1 {
- j_proxy_list = strings.Split(t.response, "\n")
- } else if strings.Index(t.response, "\\n") > -1 {
- j_proxy_list = strings.Split(t.response, "\\n")
- } else if strings.Index(t.response, " ") > -1 {
- j_proxy_list = strings.Split(t.response, " ")
- } else if strings.Index(t.response, "<br/>") > -1 {
- j_proxy_list = strings.Split(t.response, "<br/>")
- } else {
- j_proxy_list = append(j_proxy_list, t.response)
- }
- t.time_last, j_time = j_time, j_time+t.valid_time-t.failure_time
- for j_i := 0; j_i < len(j_proxy_list); j_i++ {
- j_proxy_info := &pool_item{Info: yu_proxy.NewInfo().SetAuthorization(t.user, t.pass)}
- if strings.Index(j_proxy_list[j_i], " ") > -1 {
- if j_ip_port := strings.Split(j_proxy_list[j_i], " "); len(j_ip_port) == 3 {
- j_proxy_list[j_i] = j_ip_port[0]
- j_proxy_info.User, j_proxy_info.Pass = j_ip_port[1], j_ip_port[2]
- }
- }
- if strings.Count(j_proxy_list[j_i], ".") == 3 && strings.Count(j_proxy_list[j_i], ":") == 1 {
- j_addr := strings.Split(j_proxy_list[j_i], ":")
- 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
- t.list = append(t.list, j_proxy_info)
- }
- }
- return len(t.list) > 0
- } else if t.url_type == 1 {
- j_len := 100
- t.list = make([]*pool_item, j_len)
- for j_num := 0; j_num < j_len; j_num++ {
- t.list[j_num] = &pool_item{}
- t.list[j_num].Info = yu_proxy.NewInfo()
- t.list[j_num].Host = t.url
- t.list[j_num].User = t.user
- t.list[j_num].Pass = t.pass
- t.list[j_num].Type = t._type
- t.list[j_num].Timeout = -1
- t.list[j_num].Domain = t.domain
- }
- return true
- }
- return false
- }
|