package windscribe import ( "bufio" "context" "encoding/json" "fmt" "io" "net/http" "regexp" "strconv" "strings" ) type csrf struct { Token string `json:"csrf_token"` Time int `json:"csrf_time"` } func (c *client) getCSRF(ctx context.Context) (*csrf, error) { req, err := http.NewRequestWithContext(ctx, "POST", "https://res.windscribe.com/res/logintoken", strings.NewReader("")) if err != nil { return nil, err } fillReq(req) resp, err := c.hc.Do(req) if err != nil { return nil, err } var csrf csrf decoder := json.NewDecoder(resp.Body) err = decoder.Decode(&csrf) if err != nil { return nil, err } cleanupBody(resp.Body) return &csrf, nil } var csrfRE = regexp.MustCompile(`^\s*csrf_(time|token) = '?([0-9a-f]+)'?;\s*$`) func (c *client) getCSRFfromBody(ctx context.Context, body io.Reader) (*csrf, error) { csrf := csrf{} scan := bufio.NewScanner(body) for scan.Scan() { ln := scan.Text() m := csrfRE.FindStringSubmatch(ln) if len(m) == 3 { var err error switch m[1] { case "time": csrf.Time, err = strconv.Atoi(m[2]) if err != nil { return nil, err } case "token": csrf.Token = m[2] } } } if err := scan.Err(); err != nil { return nil, err } if csrf.Token == "" || csrf.Time == 0 { return nil, fmt.Errorf("getCSRFfromBody: csrf is %+v", csrf) } return &csrf, nil }