feat: Sora 请求优先走 curl_cffi sidecar(Chrome 指纹绕过 Cloudflare)
This commit is contained in:
parent
0bfd6edde6
commit
fba8cc82ae
@ -478,7 +478,7 @@ func (c *SoraSDKClient) GetWatermarkFreeURLCustom(ctx context.Context, account *
|
||||
}
|
||||
var resp *http.Response
|
||||
if c.httpUpstream != nil {
|
||||
resp, err = c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
||||
resp, err = c.doSoraHTTP(req, proxyURL, accountID, accountConcurrency)
|
||||
} else {
|
||||
resp, err = http.DefaultClient.Do(req)
|
||||
}
|
||||
@ -901,7 +901,7 @@ func (c *SoraSDKClient) exchangeSessionToken(ctx context.Context, account *Accou
|
||||
|
||||
var resp *http.Response
|
||||
if c.httpUpstream != nil {
|
||||
resp, err = c.httpUpstream.Do(req, proxyURL, accountID, accountConcurrency)
|
||||
resp, err = c.doSoraHTTP(req, proxyURL, accountID, accountConcurrency)
|
||||
} else {
|
||||
resp, err = http.DefaultClient.Do(req)
|
||||
}
|
||||
@ -1024,3 +1024,70 @@ func (c *SoraSDKClient) debugLogf(format string, args ...any) {
|
||||
log.Printf("[SoraSDK] "+format, args...)
|
||||
}
|
||||
}
|
||||
|
||||
// doSoraHTTP 执行 Sora HTTP 请求,优先走 curl_cffi sidecar(Chrome TLS 指纹绕过 Cloudflare)
|
||||
// 如果 sidecar 未启用或不可用,回退到 httpUpstream.Do() / http.DefaultClient
|
||||
func (c *SoraSDKClient) doSoraHTTP(req *http.Request, proxyURL string, accountID int64, accountConcurrency int) (*http.Response, error) {
|
||||
// 检查 sidecar 是否启用
|
||||
if c.cfg != nil && c.cfg.Sora.Client.CurlCFFISidecar.Enabled && c.cfg.Sora.Client.CurlCFFISidecar.BaseURL != "" {
|
||||
resp, err := c.doViaSidecar(req)
|
||||
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) (*http.Response, error) {
|
||||
sidecarURL := strings.TrimRight(c.cfg.Sora.Client.CurlCFFISidecar.BaseURL, "/") + "/proxy"
|
||||
|
||||
// 读取原始请求体
|
||||
var bodyStr string
|
||||
if originalReq.Body != nil {
|
||||
bodyBytes, err := io.ReadAll(originalReq.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read request body: %w", err)
|
||||
}
|
||||
bodyStr = string(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": bodyStr,
|
||||
"session_key": fmt.Sprintf("account_%d", 0), // 简单的 session key
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user