diff --git a/go.mod b/go.mod index e589003..15a5466 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ -module github.com/y-a-t-s/libkiwi +module gitgud.io/yats/libkiwi go 1.25.6 -require github.com/y-a-t-s/firebird v0.0.0-20251115152558-29bf6ad7c90b +require github.com/y-a-t-s/cerberus v0.0.0-20260209172955-b5a3082a97ee require ( github.com/klauspost/cpuid/v2 v2.2.3 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - golang.org/x/net v0.28.0 // indirect - golang.org/x/sys v0.23.0 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.40.0 // indirect ) diff --git a/go.sum b/go.sum index b234a28..b8c5024 100644 --- a/go.sum +++ b/go.sum @@ -2,10 +2,12 @@ github.com/klauspost/cpuid/v2 v2.2.3 h1:sxCkb+qR91z4vsqw4vGGZlDgPz3G7gjaLyK3V8y7 github.com/klauspost/cpuid/v2 v2.2.3/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/y-a-t-s/firebird v0.0.0-20251115152558-29bf6ad7c90b h1:tAqjNda25c1SpnoDmDx5b1KIuN0VTgskoU4shwSMdFI= -github.com/y-a-t-s/firebird v0.0.0-20251115152558-29bf6ad7c90b/go.mod h1:/qomDTP1XQRFc0TLzcf0Y5wMHftgl5z40PAb9aTxXGg= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +github.com/y-a-t-s/cerberus v0.0.0-20260204195623-34ceeced8f89 h1:mlG5ck3Of8vNKPZX/RXs7T+kJPcsLsK8hcG0kAQScc0= +github.com/y-a-t-s/cerberus v0.0.0-20260204195623-34ceeced8f89/go.mod h1:CO0/MIkpLBFxuhP1+j7u+IN4JRBSIzk8MNnSIGsmenI= +github.com/y-a-t-s/cerberus v0.0.0-20260209172955-b5a3082a97ee h1:DWnyTaXLd4F3Digp8NVD4v/IOH13VwLc07Jh5eeKxfM= +github.com/y-a-t-s/cerberus v0.0.0-20260209172955-b5a3082a97ee/go.mod h1:CO0/MIkpLBFxuhP1+j7u+IN4JRBSIzk8MNnSIGsmenI= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= +golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= diff --git a/libkiwi.go b/libkiwi.go index eb83750..06d76c5 100644 --- a/libkiwi.go +++ b/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 } diff --git a/libkiwi_test.go b/libkiwi_test.go index 8d951d4..c66131c 100644 --- a/libkiwi_test.go +++ b/libkiwi_test.go @@ -7,7 +7,7 @@ import ( "testing" ) -const TEST_HOST = "kiwifarms.net" +const TEST_HOST = "kiwifarms.st" func TestGetPage(t *testing.T) { cookies := os.Getenv("TEST_COOKIES")