mirror of
https://gitgud.io/yats/libkiwi.git
synced 2026-05-02 02:32:05 -04:00
Cerberus support
This commit is contained in:
69
libkiwi.go
69
libkiwi.go
@@ -3,13 +3,14 @@ package libkiwi
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/y-a-t-s/firebird"
|
||||
"github.com/y-a-t-s/cerberus"
|
||||
)
|
||||
|
||||
type KF struct {
|
||||
@@ -18,28 +19,27 @@ type KF struct {
|
||||
}
|
||||
|
||||
// Supply your own http.Client to route through any proxies.
|
||||
func NewKF(hc http.Client, host string, cookies string) (kf *KF, err error) {
|
||||
func NewKF(hc http.Client, host string, cookies string) (KF, error) {
|
||||
u, err := parseHost(host)
|
||||
if err != nil {
|
||||
return
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if hc.Jar == nil {
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return KF{}, err
|
||||
}
|
||||
hc.Jar = jar
|
||||
}
|
||||
|
||||
cs, err := parseCookieString(u, cookies)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if cookies != "" {
|
||||
cs, err := parseCookieString(u, cookies)
|
||||
if err != nil {
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
jar.SetCookies(u, cs)
|
||||
hc.Jar = jar
|
||||
|
||||
kf = &KF{
|
||||
Client: hc,
|
||||
domain: u,
|
||||
hc.Jar.SetCookies(u, cs)
|
||||
}
|
||||
|
||||
// Update host url in case we get redirected across domains.
|
||||
@@ -54,7 +54,10 @@ func NewKF(hc http.Client, host string, cookies string) (kf *KF, err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return
|
||||
return KF{
|
||||
Client: hc,
|
||||
domain: u,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (kf *KF) GetPage(ctx context.Context, u *url.URL) (*http.Response, error) {
|
||||
@@ -76,7 +79,7 @@ func (kf *KF) GetPage(ctx context.Context, u *url.URL) (*http.Response, error) {
|
||||
|
||||
// KiwiFlare redirect is signaled by 203 status.
|
||||
if resp.StatusCode == 203 {
|
||||
err = kf.solveKiwiFlare(ctx)
|
||||
err = kf.SolveKiwiFlare(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,22 +112,29 @@ func parseCookieString(u *url.URL, cookies string) ([]*http.Cookie, error) {
|
||||
|
||||
func setCookie(jar http.CookieJar, u *url.URL, cookie *http.Cookie) {
|
||||
cookies := jar.Cookies(u)
|
||||
found := false
|
||||
|
||||
for i, c := range cookies {
|
||||
if c.Name == cookie.Name {
|
||||
cookies[i] = cookie
|
||||
found = true
|
||||
break
|
||||
// Store changes and stop looping since it's found.
|
||||
jar.SetCookies(u, cookies)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
cookies = append(cookies, cookie)
|
||||
}
|
||||
|
||||
// Append new cookie if existing one not found.
|
||||
cookies = append(cookies, cookie)
|
||||
jar.SetCookies(u, cookies)
|
||||
}
|
||||
|
||||
func (kf *KF) CookieString() string {
|
||||
var b strings.Builder
|
||||
for _, c := range kf.Client.Jar.Cookies(kf.domain) {
|
||||
fmt.Fprintf(&b, "%s: %s; ", c.Name, c.Value)
|
||||
}
|
||||
return strings.TrimSuffix(b.String(), "; ")
|
||||
}
|
||||
|
||||
func (kf *KF) RefreshSession(ctx context.Context) (string, error) {
|
||||
// Clear any existing session token to request a new one.
|
||||
setCookie(kf.Client.Jar, kf.domain, &http.Cookie{
|
||||
@@ -141,19 +151,20 @@ func (kf *KF) RefreshSession(ctx context.Context) (string, error) {
|
||||
return regexp.MustCompile(`xf_session=([^;]*)`).FindString(resp.Header.Get("Set-Cookie")), nil
|
||||
}
|
||||
|
||||
func (kf *KF) solveKiwiFlare(ctx context.Context) error {
|
||||
c, err := firebird.NewChallenge(kf.Client, kf.domain.String())
|
||||
func (kf *KF) SolveKiwiFlare(ctx context.Context) error {
|
||||
c, err := cerberus.NewChallenge(ctx, kf.Client, kf.domain.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s, err := firebird.Solve(ctx, c)
|
||||
s, err := cerberus.Solve(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = firebird.Submit(kf.Client, s)
|
||||
resp, err := cerberus.Submit(ctx, kf.Client, s, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user