mirror of
https://github.com/coaidev/coai.git
synced 2025-05-19 13:00:14 +09:00
feat: support authentication in http/https/socks5 proxies (#126)
This commit is contained in:
parent
3f7e3f9d4b
commit
93c18bb34c
@ -23,6 +23,8 @@ export type Channel = {
|
||||
proxy?: {
|
||||
proxy: string;
|
||||
proxy_type: number;
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,13 @@ import ChannelTable from "@/components/admin/assemblies/ChannelTable.tsx";
|
||||
import ChannelEditor from "@/components/admin/assemblies/ChannelEditor.tsx";
|
||||
import { Channel, getChannelInfo } from "@/admin/channel.ts";
|
||||
|
||||
const initialProxyState = {
|
||||
proxy: "",
|
||||
proxy_type: 0,
|
||||
username: "",
|
||||
password: "",
|
||||
};
|
||||
|
||||
const initialState: Channel = {
|
||||
id: -1,
|
||||
type: "openai",
|
||||
@ -16,10 +23,7 @@ const initialState: Channel = {
|
||||
mapper: "",
|
||||
state: true,
|
||||
group: [],
|
||||
proxy: {
|
||||
proxy: "",
|
||||
proxy_type: 0,
|
||||
},
|
||||
proxy: { ...initialProxyState },
|
||||
};
|
||||
|
||||
function reducer(state: Channel, action: any): Channel {
|
||||
@ -87,6 +91,8 @@ function reducer(state: Channel, action: any): Channel {
|
||||
proxy: {
|
||||
proxy: action.value as string,
|
||||
proxy_type: state?.proxy?.proxy_type || 0,
|
||||
password: state?.proxy?.password || "",
|
||||
username: state?.proxy?.username || "",
|
||||
},
|
||||
};
|
||||
case "set-proxy-type":
|
||||
@ -95,6 +101,28 @@ function reducer(state: Channel, action: any): Channel {
|
||||
proxy: {
|
||||
proxy: state?.proxy?.proxy || "",
|
||||
proxy_type: action.value as number,
|
||||
password: state?.proxy?.password || "",
|
||||
username: state?.proxy?.username || "",
|
||||
},
|
||||
};
|
||||
case "set-proxy-username":
|
||||
return {
|
||||
...state,
|
||||
proxy: {
|
||||
proxy: state?.proxy?.proxy || "",
|
||||
proxy_type: state?.proxy?.proxy_type || 0,
|
||||
password: state?.proxy?.password || "",
|
||||
username: action.value as string,
|
||||
},
|
||||
};
|
||||
case "set-proxy-password":
|
||||
return {
|
||||
...state,
|
||||
proxy: {
|
||||
proxy: state?.proxy?.proxy || "",
|
||||
proxy_type: state?.proxy?.proxy_type || 0,
|
||||
password: action.value as string,
|
||||
username: state?.proxy?.username || "",
|
||||
},
|
||||
};
|
||||
case "set":
|
||||
|
@ -453,6 +453,38 @@ function ChannelEditor({
|
||||
disabled={edit.proxy?.proxy_type === 0}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphItem>
|
||||
<div className={`channel-content`}>
|
||||
{t("admin.channels.proxy-username")}
|
||||
</div>
|
||||
<Input
|
||||
value={edit.proxy?.username || ""}
|
||||
placeholder={t("admin.channels.proxy-username-placeholder")}
|
||||
onChange={(e) =>
|
||||
dispatch({
|
||||
type: "set-proxy-username",
|
||||
value: e.target.value,
|
||||
})
|
||||
}
|
||||
disabled={edit.proxy?.proxy_type === 0}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphItem>
|
||||
<div className={`channel-content`}>
|
||||
{t("admin.channels.proxy-password")}
|
||||
</div>
|
||||
<Input
|
||||
value={edit.proxy?.password || ""}
|
||||
placeholder={t("admin.channels.proxy-password-placeholder")}
|
||||
onChange={(e) =>
|
||||
dispatch({
|
||||
type: "set-proxy-password",
|
||||
value: e.target.value,
|
||||
})
|
||||
}
|
||||
disabled={edit.proxy?.proxy_type === 0}
|
||||
/>
|
||||
</ParagraphItem>
|
||||
<ParagraphDescription>
|
||||
{t("admin.channels.proxy-desc")}
|
||||
</ParagraphDescription>
|
||||
|
@ -100,7 +100,7 @@ function SyncDialog({ dispatch, open, setOpen }: SyncDialogProps) {
|
||||
mapper: "",
|
||||
state: true,
|
||||
group: [],
|
||||
proxy: { proxy: "", proxy_type: 0 },
|
||||
proxy: { proxy: "", proxy_type: 0, username: "", password: "" },
|
||||
};
|
||||
|
||||
dispatch({ type: "set", value: data });
|
||||
|
@ -633,6 +633,10 @@
|
||||
"proxy-type": "代理类型",
|
||||
"proxy-endpoint": "代理地址",
|
||||
"proxy-endpoint-placeholder": "请输入正向代理地址,如:socks5://example.com:1080",
|
||||
"proxy-username": "代理用户名",
|
||||
"proxy-username-placeholder": "请输入代理的鉴权用户名 (可选)",
|
||||
"proxy-password": "代理密码",
|
||||
"proxy-password-placeholder": "请输入代理的鉴权密码 (可选)",
|
||||
"proxy-desc": "正向代理,支持 HTTP/HTTPS/SOCKS5 代理 (反向代理请填写接入点, 非特殊情况无需设置正向代理)"
|
||||
},
|
||||
"charge": {
|
||||
|
@ -461,7 +461,11 @@
|
||||
"proxy-type": "Delegate Type",
|
||||
"proxy-endpoint": "proxy address",
|
||||
"proxy-endpoint-placeholder": "Please enter forward proxy address, ex: socks5://example.com: 1080",
|
||||
"proxy-desc": "Forward proxy, supports HTTP/HTTPS/SOCKS5 proxy (reverse proxy please fill in the access point, no need to set forward proxy in non-special cases)"
|
||||
"proxy-desc": "Forward proxy, supports HTTP/HTTPS/SOCKS5 proxy (reverse proxy please fill in the access point, no need to set forward proxy in non-special cases)",
|
||||
"proxy-username": "Proxy User",
|
||||
"proxy-username-placeholder": "Please enter the agent's authentication username (optional)",
|
||||
"proxy-password": "Proxy password",
|
||||
"proxy-password-placeholder": "Please enter the agent's authentication password (optional)"
|
||||
},
|
||||
"charge": {
|
||||
"id": "ID",
|
||||
|
@ -461,7 +461,11 @@
|
||||
"proxy-type": "プロキシのタイプ",
|
||||
"proxy-endpoint": "プロキシアドレス",
|
||||
"proxy-endpoint-placeholder": "転送プロキシアドレスを入力してください。例: socks 5 :// example.com: 1080",
|
||||
"proxy-desc": "フォワードプロキシ、HTTP/HTTPS/SOCKS 5プロキシをサポート(リバースプロキシはアクセスポイントに記入してください。特別な場合以外はフォワードプロキシを設定する必要はありません)"
|
||||
"proxy-desc": "フォワードプロキシ、HTTP/HTTPS/SOCKS 5プロキシをサポート(リバースプロキシはアクセスポイントに記入してください。特別な場合以外はフォワードプロキシを設定する必要はありません)",
|
||||
"proxy-username": "プロキシユーザー名",
|
||||
"proxy-username-placeholder": "エージェントの認証ユーザー名を入力してください(オプション)",
|
||||
"proxy-password": "プロキシパスワード",
|
||||
"proxy-password-placeholder": "エージェントの認証パスワードを入力してください(オプション)"
|
||||
},
|
||||
"charge": {
|
||||
"id": "ID",
|
||||
|
@ -461,7 +461,11 @@
|
||||
"proxy-type": "Тип прокси- сервера",
|
||||
"proxy-endpoint": "Адрес прокси-сервера",
|
||||
"proxy-endpoint-placeholder": "Введите адрес прямого прокси-сервера, например: socks5://example.com: 1080",
|
||||
"proxy-desc": "Прямой прокси-сервер, поддерживает HTTP/HTTPS/Socks5 прокси-сервер (обратный прокси-сервер, пожалуйста, заполните точку доступа, нет необходимости устанавливать прокси-сервер в неспециальных случаях)"
|
||||
"proxy-desc": "Прямой прокси-сервер, поддерживает HTTP/HTTPS/Socks5 прокси-сервер (обратный прокси-сервер, пожалуйста, заполните точку доступа, нет необходимости устанавливать прокси-сервер в неспециальных случаях)",
|
||||
"proxy-username": "Имя пользователя прокси-сервера",
|
||||
"proxy-username-placeholder": "Введите имя пользователя для аутентификации агента (необязательно)",
|
||||
"proxy-password": "Пароль прокси-сервера",
|
||||
"proxy-password-placeholder": "Введите пароль аутентификации агента (необязательно)"
|
||||
},
|
||||
"charge": {
|
||||
"id": "ID",
|
||||
|
@ -49,4 +49,6 @@ type ListModelsItem struct {
|
||||
type ProxyConfig struct {
|
||||
ProxyType int `json:"proxy_type" mapstructure:"proxytype"`
|
||||
Proxy string `json:"proxy" mapstructure:"proxy"`
|
||||
Username string `json:"username" mapstructure:"username"`
|
||||
Password string `json:"password" mapstructure:"password"`
|
||||
}
|
||||
|
14
utils/net.go
14
utils/net.go
@ -38,6 +38,10 @@ func newClient(c []globals.ProxyConfig) *http.Client {
|
||||
|
||||
if config.ProxyType == globals.HttpProxyType || config.ProxyType == globals.HttpsProxyType {
|
||||
proxyUrl, err := url.Parse(config.Proxy)
|
||||
if len(config.Username) > 0 || len(config.Password) > 0 {
|
||||
proxyUrl.User = url.UserPassword(config.Username, config.Password)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
globals.Warn(fmt.Sprintf("failed to parse proxy url: %s", err))
|
||||
return client
|
||||
@ -47,7 +51,15 @@ func newClient(c []globals.ProxyConfig) *http.Client {
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
} else if config.ProxyType == globals.Socks5ProxyType {
|
||||
dialer, err := proxy.SOCKS5("tcp", config.Proxy, nil, proxy.Direct)
|
||||
var auth *proxy.Auth
|
||||
if len(config.Username) > 0 || len(config.Password) > 0 {
|
||||
auth = &proxy.Auth{
|
||||
User: config.Username,
|
||||
Password: config.Password,
|
||||
}
|
||||
}
|
||||
|
||||
dialer, err := proxy.SOCKS5("tcp", config.Proxy, auth, proxy.Direct)
|
||||
if err != nil {
|
||||
globals.Warn(fmt.Sprintf("failed to create socks5 proxy: %s", err))
|
||||
return client
|
||||
|
Loading…
Reference in New Issue
Block a user