mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 04:50:52 +08:00
Merge pull request #58 from router-for-me/v6-test
refactor(gemini-web): Remove auto-refresh, auto-close, and caching
This commit is contained in:
@@ -5,8 +5,6 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -18,15 +16,13 @@ import (
|
||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/constant"
|
||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/interfaces"
|
||||
"github.com/router-for-me/CLIProxyAPI/v6/internal/translator/translator"
|
||||
cliproxyauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
|
||||
cliproxyexecutor "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/executor"
|
||||
"github.com/tidwall/gjson"
|
||||
"github.com/tidwall/sjson"
|
||||
)
|
||||
|
||||
const (
|
||||
geminiWebDefaultTimeoutSec = 300
|
||||
geminiWebDefaultRefreshIntervalSec = 540
|
||||
geminiWebDefaultTimeoutSec = 300
|
||||
)
|
||||
|
||||
type geminiWebState struct {
|
||||
@@ -48,15 +44,7 @@ type geminiWebState struct {
|
||||
convData map[string]geminiwebapi.ConversationRecord
|
||||
convIndex map[string]string
|
||||
|
||||
refreshInterval time.Duration
|
||||
lastRefresh time.Time
|
||||
}
|
||||
|
||||
func (s *geminiWebState) RefreshLead() time.Duration {
|
||||
if s.refreshInterval > 0 {
|
||||
return s.refreshInterval
|
||||
}
|
||||
return 9 * time.Minute
|
||||
lastRefresh time.Time
|
||||
}
|
||||
|
||||
func newGeminiWebState(cfg *config.Config, token *gemini.GeminiWebTokenStorage, storagePath string) *geminiWebState {
|
||||
@@ -84,11 +72,6 @@ func newGeminiWebState(cfg *config.Config, token *gemini.GeminiWebTokenStorage,
|
||||
state.accountID = suffix
|
||||
}
|
||||
state.loadConversationCaches()
|
||||
intervalSec := geminiWebDefaultRefreshIntervalSec
|
||||
if cfg != nil && cfg.GeminiWeb.TokenRefreshSeconds > 0 {
|
||||
intervalSec = cfg.GeminiWeb.TokenRefreshSeconds
|
||||
}
|
||||
state.refreshInterval = time.Duration(intervalSec) * time.Second
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -136,15 +119,9 @@ func (s *geminiWebState) ensureClient() error {
|
||||
s.token.Secure1PSID,
|
||||
s.token.Secure1PSIDTS,
|
||||
proxyURL,
|
||||
geminiwebapi.WithOnCookiesRefreshed(s.onCookiesRefreshed),
|
||||
)
|
||||
timeout := geminiWebDefaultTimeoutSec
|
||||
refresh := geminiWebDefaultRefreshIntervalSec
|
||||
if s.cfg != nil && s.cfg.GeminiWeb.TokenRefreshSeconds > 0 {
|
||||
refresh = s.cfg.GeminiWeb.TokenRefreshSeconds
|
||||
}
|
||||
// Use explicit refresh; background auto-refresh disabled here
|
||||
if err := s.client.Init(float64(timeout), false, 300, false, float64(refresh), false); err != nil {
|
||||
if err := s.client.Init(float64(timeout), false); err != nil {
|
||||
s.client = nil
|
||||
return err
|
||||
}
|
||||
@@ -162,38 +139,25 @@ func (s *geminiWebState) refresh(ctx context.Context) error {
|
||||
s.token.Secure1PSID,
|
||||
s.token.Secure1PSIDTS,
|
||||
proxyURL,
|
||||
geminiwebapi.WithOnCookiesRefreshed(s.onCookiesRefreshed),
|
||||
)
|
||||
timeout := geminiWebDefaultTimeoutSec
|
||||
refresh := geminiWebDefaultRefreshIntervalSec
|
||||
if s.cfg != nil && s.cfg.GeminiWeb.TokenRefreshSeconds > 0 {
|
||||
refresh = s.cfg.GeminiWeb.TokenRefreshSeconds
|
||||
}
|
||||
// Use explicit refresh; background auto-refresh disabled here
|
||||
if err := s.client.Init(float64(timeout), false, 300, false, float64(refresh), false); err != nil {
|
||||
if err := s.client.Init(float64(timeout), false); err != nil {
|
||||
return err
|
||||
}
|
||||
// Attempt rotation proactively to persist new TS sooner
|
||||
_ = s.tryRotatePSIDTS(proxyURL)
|
||||
if newTS, err := s.client.RotateTS(); err == nil && newTS != "" && newTS != s.token.Secure1PSIDTS {
|
||||
s.tokenMu.Lock()
|
||||
s.token.Secure1PSIDTS = newTS
|
||||
s.tokenDirty = true
|
||||
if s.client != nil && s.client.Cookies != nil {
|
||||
s.client.Cookies["__Secure-1PSIDTS"] = newTS
|
||||
}
|
||||
s.tokenMu.Unlock()
|
||||
}
|
||||
s.lastRefresh = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *geminiWebState) onCookiesRefreshed() {
|
||||
s.tokenMu.Lock()
|
||||
defer s.tokenMu.Unlock()
|
||||
if s.client == nil || s.client.Cookies == nil {
|
||||
return
|
||||
}
|
||||
if v := s.client.Cookies["__Secure-1PSID"]; v != "" {
|
||||
s.token.Secure1PSID = v
|
||||
}
|
||||
if v := s.client.Cookies["__Secure-1PSIDTS"]; v != "" {
|
||||
s.token.Secure1PSIDTS = v
|
||||
}
|
||||
s.tokenDirty = true
|
||||
}
|
||||
|
||||
func (s *geminiWebState) tokenSnapshot() *gemini.GeminiWebTokenStorage {
|
||||
s.tokenMu.Lock()
|
||||
defer s.tokenMu.Unlock()
|
||||
@@ -201,70 +165,6 @@ func (s *geminiWebState) tokenSnapshot() *gemini.GeminiWebTokenStorage {
|
||||
return &c
|
||||
}
|
||||
|
||||
// tryRotatePSIDTS performs a best-effort rotation of __Secure-1PSIDTS using
|
||||
// the public RotateCookies endpoint. On success it updates both the in-memory
|
||||
// token and the live client's cookie jar so that subsequent requests adopt the
|
||||
// new value. Any error is ignored by the caller to avoid disrupting refresh.
|
||||
func (s *geminiWebState) tryRotatePSIDTS(proxy string) error {
|
||||
cookies := map[string]string{
|
||||
"__Secure-1PSID": s.token.Secure1PSID,
|
||||
"__Secure-1PSIDTS": s.token.Secure1PSIDTS,
|
||||
}
|
||||
|
||||
tr := &http.Transport{}
|
||||
if proxy != "" {
|
||||
if pu, err := url.Parse(proxy); err == nil {
|
||||
tr.Proxy = http.ProxyURL(pu)
|
||||
}
|
||||
}
|
||||
client := &http.Client{Transport: tr, Timeout: 60 * time.Second}
|
||||
|
||||
req, _ := http.NewRequest(http.MethodPost, geminiwebapi.EndpointRotateCookies, bytes.NewReader([]byte("[000,\"-0000000000000000000\"]")))
|
||||
for k, vs := range geminiwebapi.HeadersRotateCookies {
|
||||
for _, v := range vs {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
}
|
||||
for k, v := range cookies {
|
||||
req.AddCookie(&http.Cookie{Name: k, Value: v})
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
for _, c := range resp.Cookies() {
|
||||
if c == nil {
|
||||
continue
|
||||
}
|
||||
if c.Name == "__Secure-1PSIDTS" && c.Value != "" && c.Value != s.token.Secure1PSIDTS {
|
||||
s.tokenMu.Lock()
|
||||
s.token.Secure1PSIDTS = c.Value
|
||||
s.tokenDirty = true
|
||||
if s.client != nil && s.client.Cookies != nil {
|
||||
s.client.Cookies["__Secure-1PSIDTS"] = c.Value
|
||||
}
|
||||
s.tokenMu.Unlock()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *geminiWebState) ShouldRefresh(now time.Time, _ *cliproxyauth.Auth) bool {
|
||||
interval := s.refreshInterval
|
||||
if interval <= 0 {
|
||||
interval = time.Duration(geminiWebDefaultRefreshIntervalSec) * time.Second
|
||||
}
|
||||
if s.lastRefresh.IsZero() {
|
||||
return true
|
||||
}
|
||||
return now.Sub(s.lastRefresh) >= interval
|
||||
}
|
||||
|
||||
type geminiWebPrepared struct {
|
||||
handlerType string
|
||||
translatedRaw []byte
|
||||
|
||||
Reference in New Issue
Block a user