revert: 移除 Sora sidecar,还原 sora_sdk_client.go 到原版
This commit is contained in:
parent
a16db8e367
commit
3f93d5d7bf
@ -3,7 +3,6 @@ package service
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/base64"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -479,7 +478,7 @@ func (c *SoraSDKClient) GetWatermarkFreeURLCustom(ctx context.Context, account *
|
|||||||
}
|
}
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
if c.httpUpstream != nil {
|
if c.httpUpstream != nil {
|
||||||
resp, err = c.doSoraHTTP(req, proxyURL, accountID, accountConcurrency)
|
resp, err = c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
||||||
} else {
|
} else {
|
||||||
resp, err = http.DefaultClient.Do(req)
|
resp, err = http.DefaultClient.Do(req)
|
||||||
}
|
}
|
||||||
@ -724,7 +723,7 @@ func (c *SoraSDKClient) doSoraBackendJSON(
|
|||||||
|
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
if c.httpUpstream != nil {
|
if c.httpUpstream != nil {
|
||||||
resp, err = c.doSoraHTTP(req, proxyURL, accountID, accountConcurrency)
|
resp, err = c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
||||||
} else {
|
} else {
|
||||||
resp, err = http.DefaultClient.Do(req)
|
resp, err = http.DefaultClient.Do(req)
|
||||||
}
|
}
|
||||||
@ -902,7 +901,7 @@ func (c *SoraSDKClient) exchangeSessionToken(ctx context.Context, account *Accou
|
|||||||
|
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
if c.httpUpstream != nil {
|
if c.httpUpstream != nil {
|
||||||
resp, err = c.doSoraHTTP(req, proxyURL, accountID, accountConcurrency)
|
resp, err = c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
||||||
} else {
|
} else {
|
||||||
resp, err = http.DefaultClient.Do(req)
|
resp, err = http.DefaultClient.Do(req)
|
||||||
}
|
}
|
||||||
@ -1025,79 +1024,3 @@ func (c *SoraSDKClient) debugLogf(format string, args ...any) {
|
|||||||
log.Printf("[SoraSDK] "+format, args...)
|
log.Printf("[SoraSDK] "+format, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// doSoraHTTP 执行 Sora HTTP 请求,优先走 curl_cffi sidecar(Chrome TLS 指纹绕过 Cloudflare)
|
|
||||||
// 如果 sidecar 未启用、账号有独立代理、或 sidecar 不可用,回退到 httpUpstream.Do()
|
|
||||||
func (c *SoraSDKClient) doSoraHTTP(req *http.Request, proxyURL string, accountID int64, accountConcurrency int) (*http.Response, error) {
|
|
||||||
// 如果账号配置了独立代理,跳过 sidecar(sidecar 不支持 per-account 代理)
|
|
||||||
if proxyURL != "" {
|
|
||||||
if c.httpUpstream != nil {
|
|
||||||
return c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
|
||||||
}
|
|
||||||
return http.DefaultClient.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查 sidecar 是否启用
|
|
||||||
if c.cfg != nil && c.cfg.Sora.Client.CurlCFFISidecar.Enabled && c.cfg.Sora.Client.CurlCFFISidecar.BaseURL != "" {
|
|
||||||
resp, err := c.doViaSidecar(req, accountID)
|
|
||||||
if err == nil {
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
// sidecar 失败,回退到直连
|
|
||||||
logger.LegacyPrintf("service.sora", "Warning: sidecar failed, falling back to direct: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 回退路径
|
|
||||||
if c.httpUpstream != nil {
|
|
||||||
return c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
|
||||||
}
|
|
||||||
return http.DefaultClient.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
// doViaSidecar 通过 curl_cffi sidecar 发送请求(Chrome TLS 指纹)
|
|
||||||
func (c *SoraSDKClient) doViaSidecar(originalReq *http.Request, accountID int64) (*http.Response, error) {
|
|
||||||
sidecarURL := strings.TrimRight(c.cfg.Sora.Client.CurlCFFISidecar.BaseURL, "/") + "/proxy"
|
|
||||||
|
|
||||||
// 读取原始请求体,用 base64 编码(安全传输二进制数据)
|
|
||||||
var bodyB64 string
|
|
||||||
if originalReq.Body != nil {
|
|
||||||
bodyBytes, err := io.ReadAll(originalReq.Body)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("read request body: %w", err)
|
|
||||||
}
|
|
||||||
bodyB64 = base64.StdEncoding.EncodeToString(bodyBytes)
|
|
||||||
// 恢复 body 以备回退
|
|
||||||
originalReq.Body = io.NopCloser(bytes.NewReader(bodyBytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建 sidecar 请求
|
|
||||||
headers := make(map[string]string)
|
|
||||||
for k, vs := range originalReq.Header {
|
|
||||||
if len(vs) > 0 {
|
|
||||||
headers[k] = vs[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := map[string]any{
|
|
||||||
"url": originalReq.URL.String(),
|
|
||||||
"method": originalReq.Method,
|
|
||||||
"headers": headers,
|
|
||||||
"body": bodyB64,
|
|
||||||
"is_base64": true,
|
|
||||||
"session_key": fmt.Sprintf("account_%d", accountID), // 每账号独立会话
|
|
||||||
}
|
|
||||||
|
|
||||||
payloadBytes, err := json.Marshal(payload)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("marshal sidecar payload: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := originalReq.Context()
|
|
||||||
sidecarReq, err := http.NewRequestWithContext(ctx, http.MethodPost, sidecarURL, bytes.NewReader(payloadBytes))
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("create sidecar request: %w", err)
|
|
||||||
}
|
|
||||||
sidecarReq.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
return http.DefaultClient.Do(sidecarReq)
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,17 +1,16 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Node.js TLS Proxy + Sora Sidecar Overlay
|
# Node.js TLS Proxy Overlay
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# 用法:
|
# 用法:
|
||||||
# docker compose -f docker-compose.yml -f docker-compose.tls-proxy.yml up -d
|
# docker compose -f docker-compose.yml -f docker-compose.tls-proxy.yml up -d
|
||||||
#
|
#
|
||||||
# 架构:
|
# 架构:
|
||||||
# Anthropic: sub2api → node-tls-proxy (Node.js TLS) → api.anthropic.com
|
# Anthropic: sub2api → node-tls-proxy (Node.js TLS) → api.anthropic.com
|
||||||
# Sora: sub2api → sora-curl-cffi-sidecar (Chrome TLS) → sora.chatgpt.com
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|
||||||
services:
|
services:
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# 覆盖 sub2api:加入 internal 网络 + 启用代理
|
# 覆盖 sub2api:加入 internal 网络 + 启用 Node.js TLS 代理
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
sub2api:
|
sub2api:
|
||||||
networks:
|
networks:
|
||||||
@ -23,15 +22,9 @@ services:
|
|||||||
- GATEWAY_NODE_TLS_PROXY_LISTEN_PORT=3456
|
- GATEWAY_NODE_TLS_PROXY_LISTEN_PORT=3456
|
||||||
- GATEWAY_NODE_TLS_PROXY_LISTEN_HOST=node-tls-proxy
|
- GATEWAY_NODE_TLS_PROXY_LISTEN_HOST=node-tls-proxy
|
||||||
- GATEWAY_NODE_TLS_PROXY_UPSTREAM_HOST=api.anthropic.com
|
- GATEWAY_NODE_TLS_PROXY_UPSTREAM_HOST=api.anthropic.com
|
||||||
# Sora curl_cffi sidecar(Chrome 指纹绕过 Cloudflare)
|
|
||||||
- SORA_CLIENT_CURL_CFFI_SIDECAR_ENABLED=true
|
|
||||||
- SORA_CLIENT_CURL_CFFI_SIDECAR_BASE_URL=http://sora-curl-cffi-sidecar:8080
|
|
||||||
- SORA_CLIENT_CURL_CFFI_SIDECAR_IMPERSONATE=chrome131
|
|
||||||
depends_on:
|
depends_on:
|
||||||
node-tls-proxy:
|
node-tls-proxy:
|
||||||
condition: service_healthy
|
condition: service_healthy
|
||||||
sora-curl-cffi-sidecar:
|
|
||||||
condition: service_healthy
|
|
||||||
|
|
||||||
# ===========================================================================
|
# ===========================================================================
|
||||||
# Node.js TLS Forward Proxy (Anthropic)
|
# Node.js TLS Forward Proxy (Anthropic)
|
||||||
@ -68,34 +61,6 @@ services:
|
|||||||
memory: 256M
|
memory: 256M
|
||||||
cpus: "1.0"
|
cpus: "1.0"
|
||||||
|
|
||||||
# ===========================================================================
|
|
||||||
# Sora curl_cffi Sidecar (Chrome TLS fingerprint for Cloudflare bypass)
|
|
||||||
# ===========================================================================
|
|
||||||
sora-curl-cffi-sidecar:
|
|
||||||
image: zfc931912343/sora-curl-cffi-sidecar:latest
|
|
||||||
container_name: sub2api-sora-sidecar
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- PORT=8080
|
|
||||||
- IMPERSONATE=chrome131
|
|
||||||
- TIMEOUT_SECONDS=60
|
|
||||||
- SESSION_TTL_SECONDS=3600
|
|
||||||
- TZ=${TZ:-Asia/Shanghai}
|
|
||||||
networks:
|
|
||||||
- sub2api-internal
|
|
||||||
- sub2api-external
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/health')"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 15s
|
|
||||||
deploy:
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
memory: 512M
|
|
||||||
cpus: "1.0"
|
|
||||||
|
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
# Networks
|
# Networks
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user