feat: support channel request proxy
This commit is contained in:
@@ -2,4 +2,5 @@ package constant
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
ForceFormat = "force_format" // ForceFormat 强制格式化为OpenAI格式
|
ForceFormat = "force_format" // ForceFormat 强制格式化为OpenAI格式
|
||||||
|
ChanelSettingProxy = "proxy" // Proxy 代理
|
||||||
)
|
)
|
||||||
|
|||||||
28
docs/channel/orher_setting.md
Normal file
28
docs/channel/orher_setting.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
# 渠道而外设置说明
|
||||||
|
|
||||||
|
该配置用于设置一些额外的渠道参数,可以通过 JSON 对象进行配置。主要包含以下两个设置项:
|
||||||
|
|
||||||
|
1. force_format
|
||||||
|
- 用于标识是否对数据进行强制格式化为 OpenAI 格式
|
||||||
|
- 类型为布尔值,设置为 true 时启用强制格式化
|
||||||
|
|
||||||
|
2. proxy
|
||||||
|
- 用于配置网络代理
|
||||||
|
- 类型为字符串,填写代理地址(例如 socks5 协议的代理地址)
|
||||||
|
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
## JSON 格式示例
|
||||||
|
|
||||||
|
以下是一个示例配置,启用强制格式化并设置了代理地址:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"force_format": true,
|
||||||
|
"proxy": "socks5://xxxxxxx"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
--------------------------------------------------------------
|
||||||
|
|
||||||
|
通过调整上述 JSON 配置中的值,可以灵活控制渠道的额外行为,比如是否进行格式化以及使用特定的网络代理。
|
||||||
@@ -39,7 +39,7 @@ func DoApiRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("setup request header failed: %w", err)
|
return nil, fmt.Errorf("setup request header failed: %w", err)
|
||||||
}
|
}
|
||||||
resp, err := doRequest(c, req)
|
resp, err := doRequest(c, req, info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("do request failed: %w", err)
|
return nil, fmt.Errorf("do request failed: %w", err)
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,7 @@ func DoFormRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBod
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("setup request header failed: %w", err)
|
return nil, fmt.Errorf("setup request header failed: %w", err)
|
||||||
}
|
}
|
||||||
resp, err := doRequest(c, req)
|
resp, err := doRequest(c, req, info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("do request failed: %w", err)
|
return nil, fmt.Errorf("do request failed: %w", err)
|
||||||
}
|
}
|
||||||
@@ -90,8 +90,18 @@ func DoWssRequest(a Adaptor, c *gin.Context, info *common.RelayInfo, requestBody
|
|||||||
return targetConn, nil
|
return targetConn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRequest(c *gin.Context, req *http.Request) (*http.Response, error) {
|
func doRequest(c *gin.Context, req *http.Request, info *common.RelayInfo) (*http.Response, error) {
|
||||||
resp, err := service.GetHttpClient().Do(req)
|
var client *http.Client
|
||||||
|
var err error
|
||||||
|
if proxyURL, ok := info.ChannelSetting["proxy"]; ok {
|
||||||
|
client, err = service.NewProxyHttpClient(proxyURL.(string))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("new proxy http client failed: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
client = service.GetHttpClient()
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -120,7 +130,7 @@ func DoTaskApiRequest(a TaskAdaptor, c *gin.Context, info *common.TaskRelayInfo,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("setup request header failed: %w", err)
|
return nil, fmt.Errorf("setup request header failed: %w", err)
|
||||||
}
|
}
|
||||||
resp, err := doRequest(c, req)
|
resp, err := doRequest(c, req, info.ToRelayInfo())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("do request failed: %w", err)
|
return nil, fmt.Errorf("do request failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
"one-api/common"
|
"one-api/common"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -30,3 +35,43 @@ func GetHttpClient() *http.Client {
|
|||||||
func GetImpatientHttpClient() *http.Client {
|
func GetImpatientHttpClient() *http.Client {
|
||||||
return impatientHTTPClient
|
return impatientHTTPClient
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewProxyHttpClient 创建支持代理的 HTTP 客户端
|
||||||
|
func NewProxyHttpClient(proxyURL string) (*http.Client, error) {
|
||||||
|
if proxyURL == "" {
|
||||||
|
return http.DefaultClient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析代理URL
|
||||||
|
parsedURL, err := url.Parse(proxyURL)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
switch parsedURL.Scheme {
|
||||||
|
case "http", "https":
|
||||||
|
return &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
Proxy: http.ProxyURL(parsedURL),
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
case "socks5":
|
||||||
|
// 创建 SOCKS5 代理拨号器
|
||||||
|
dialer, err := proxy.SOCKS5("tcp", parsedURL.Host, nil, proxy.Direct)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
|
return dialer.Dial(network, addr)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported proxy scheme: %s", parsedURL.Scheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -966,7 +966,6 @@ const EditChannel = (props) => {
|
|||||||
value={inputs.weight}
|
value={inputs.weight}
|
||||||
autoComplete="new-password"
|
autoComplete="new-password"
|
||||||
/>
|
/>
|
||||||
{inputs.type === 8 && (
|
|
||||||
<>
|
<>
|
||||||
<div style={{ marginTop: 10 }}>
|
<div style={{ marginTop: 10 }}>
|
||||||
<Typography.Text strong>
|
<Typography.Text strong>
|
||||||
@@ -1001,7 +1000,6 @@ const EditChannel = (props) => {
|
|||||||
{t('填入模板')}
|
{t('填入模板')}
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</>
|
</>
|
||||||
)}
|
|
||||||
</Spin>
|
</Spin>
|
||||||
</SideSheet>
|
</SideSheet>
|
||||||
</>
|
</>
|
||||||
|
|||||||
Reference in New Issue
Block a user