package srun import ( "errors" "fmt" log "github.com/sirupsen/logrus" "io" "net/http" "net/url" "regexp" "strings" "unsafe" ) func (a *Api) NewDetector() Detector { redirectReg, err := regexp.Compile( `|`, ) if err != nil { panic(err) } return Detector{ api: a, redirectReg: redirectReg, } } type Detector struct { api *Api redirectReg *regexp.Regexp // 登录页 html data page []byte } func (a *Detector) _JoinRedirectLocation(addr *url.URL, loc string) (*url.URL, error) { if loc == "" { return nil, errors.New("目标跳转地址缺失") } if strings.HasPrefix(loc, "/") { addr.Path = strings.TrimPrefix(loc, "/") return addr, nil } else { return url.Parse(loc) } } type _FollowRedirectConfig struct { // 获取到下一个请求地址时触发 onNextAddr func(addr *url.URL) error } func (a *Detector) _FollowRedirect(addr *url.URL, conf _FollowRedirectConfig) (*http.Response, []byte, error) { addrCopy := *addr addr = &addrCopy var body []byte var res *http.Response for { log.Debugln("HTTP GET", addr) req, err := http.NewRequest("GET", addr.String(), nil) if err != nil { return nil, nil, err } for k, v := range a.api.CustomHeader { req.Header.Set(k, fmt.Sprint(v)) } res, err = a.api.NoDirect.Do(req) if err != nil { return nil, nil, err } if res.StatusCode < 300 { body, err = io.ReadAll(res.Body) _ = res.Body.Close() if err != nil { return nil, nil, err } locMatch := a.redirectReg.FindSubmatch(body) if len(locMatch) > 2 { locBytes := locMatch[1] addr, err = a._JoinRedirectLocation(addr, unsafe.String(unsafe.SliceData(locBytes), len(locBytes))) if err != nil { return nil, nil, err } } else { break } } else { _, _ = io.Copy(io.Discard, res.Body) _ = res.Body.Close() if res.StatusCode < 400 { addr, err = a._JoinRedirectLocation(addr, res.Header.Get("location")) if err != nil { return nil, nil, err } } else { return nil, nil, fmt.Errorf("server return http status %d", res.StatusCode) } } if conf.onNextAddr != nil { if err = conf.onNextAddr(addr); err != nil { return nil, nil, err } } } return res, body, nil } func (a *Detector) _SearchAcid(query url.Values) (string, bool) { addr := query.Get(`ac_id`) return addr, addr != "" } func (a *Detector) DetectEnc() (string, error) { if a.page == nil { log.Debugln("HTTP GET", a.api.BaseUrl) res, err := a.api.Client.Get(a.api.BaseUrl) if err != nil { return "", err } defer res.Body.Close() if res.StatusCode != 200 { _, _ = io.Copy(io.Discard, res.Body) return "", fmt.Errorf("server return http status: %d", res.StatusCode) } a.page, err = io.ReadAll(res.Body) if err != nil { return "", err } } jsReg, err := regexp.Compile(`(?i)