🔖 chore: add chat image request proxy address

This commit is contained in:
MartialBE 2024-05-29 04:01:28 +08:00
parent 3d8a51e139
commit b5a4283b28
No known key found for this signature in database
GPG Key ID: 27C0267EC84B0A5C
11 changed files with 76 additions and 53 deletions

View File

@ -69,6 +69,8 @@ var SMTPAccount = ""
var SMTPFrom = ""
var SMTPToken = ""
var ChatImageRequestProxy = ""
var GitHubClientId = ""
var GitHubClientSecret = ""

26
common/image/http.go Normal file
View File

@ -0,0 +1,26 @@
package image
import (
"net/http"
"one-api/common/config"
"one-api/common/utils"
"time"
)
var ImageHttpClients = &http.Client{
Transport: &http.Transport{
DialContext: utils.Socks5ProxyFunc,
Proxy: utils.ProxyFunc,
},
Timeout: 15 * time.Second,
}
func requestImage(url, method string) (*http.Response, error) {
res, err := utils.RequestBuilder(utils.SetProxy(config.ChatImageRequestProxy, nil), method, url, nil, nil)
if err != nil {
return nil, err
}
return ImageHttpClients.Do(res)
}

View File

@ -16,17 +16,8 @@ import (
_ "golang.org/x/image/webp"
)
// var ImageHttpClients = &http.Client{
// Transport: &http.Transport{
// DialContext: requester.Socks5ProxyFunc,
// Proxy: requester.ProxyFunc,
// },
// //
// // // Timeout: 30 * time.Second,
// }
func IsImageUrl(url string) (bool, error) {
resp, err := http.Head(url)
resp, err := requestImage(url, http.MethodHead)
if err != nil {
return false, err
}
@ -41,7 +32,7 @@ func GetImageSizeFromUrl(url string) (width int, height int, err error) {
if !isImage {
return
}
resp, err := http.Get(url)
resp, err := requestImage(url, http.MethodGet)
if err != nil {
return
}
@ -126,6 +117,6 @@ func GetImageSize(image string) (width int, height int, err error) {
case strings.HasPrefix(image, "http"):
return GetImageSizeFromUrl(image)
default:
return 0, 0, errors.New("invalid file type, Please view request interface!")
return 0, 0, errors.New("invalid file type, please view request interface")
}
}

View File

@ -20,7 +20,7 @@ import (
type HttpErrorHandler func(*http.Response) *types.OpenAIError
type HTTPRequester struct {
requestBuilder RequestBuilder
// requestBuilder utils.RequestBuilder
CreateFormBuilder func(io.Writer) FormBuilder
ErrorHandler HttpErrorHandler
proxyAddr string
@ -34,7 +34,6 @@ type HTTPRequester struct {
// 如果 errorHandler 为 nil那么会使用一个默认的错误处理函数。
func NewHTTPRequester(proxyAddr string, errorHandler HttpErrorHandler) *HTTPRequester {
return &HTTPRequester{
requestBuilder: NewRequestBuilder(),
CreateFormBuilder: func(body io.Writer) FormBuilder {
return NewFormBuilder(body)
},
@ -53,7 +52,7 @@ type requestOptions struct {
type requestOption func(*requestOptions)
func (r *HTTPRequester) setProxy() context.Context {
return utils.SetProxy(r.Context, r.proxyAddr)
return utils.SetProxy(r.proxyAddr, r.Context)
}
// 创建请求
@ -65,7 +64,7 @@ func (r *HTTPRequester) NewRequest(method, url string, setters ...requestOption)
for _, setter := range setters {
setter(args)
}
req, err := r.requestBuilder.Build(r.setProxy(), method, url, args.body, args.header)
req, err := utils.RequestBuilder(r.setProxy(), method, url, args.body, args.header)
if err != nil {
return nil, err
}

View File

@ -1,15 +0,0 @@
package requester
import (
"encoding/json"
)
type Marshaller interface {
Marshal(value any) ([]byte, error)
}
type JSONMarshaller struct{}
func (jm *JSONMarshaller) Marshal(value any) ([]byte, error) {
return json.Marshal(value)
}

View File

@ -60,7 +60,11 @@ func Socks5ProxyFunc(ctx context.Context, network, addr string) (net.Conn, error
return proxyDialer.Dial(network, addr)
}
func SetProxy(ctx context.Context, proxyAddr string) context.Context {
func SetProxy(proxyAddr string, ctx context.Context) context.Context {
if ctx == nil {
ctx = context.Background()
}
if proxyAddr == "" {
return ctx
}

View File

@ -1,27 +1,14 @@
package requester
package utils
import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
)
type RequestBuilder interface {
Build(ctx context.Context, method, url string, body any, header http.Header) (*http.Request, error)
}
type HTTPRequestBuilder struct {
marshaller Marshaller
}
func NewRequestBuilder() *HTTPRequestBuilder {
return &HTTPRequestBuilder{
marshaller: &JSONMarshaller{},
}
}
func (b *HTTPRequestBuilder) Build(
func RequestBuilder(
ctx context.Context,
method string,
url string,
@ -34,7 +21,7 @@ func (b *HTTPRequestBuilder) Build(
bodyReader = v
} else {
var reqBytes []byte
reqBytes, err = b.marshaller.Marshal(body)
reqBytes, err = json.Marshal(body)
if err != nil {
return
}

2
go.mod
View File

@ -13,6 +13,7 @@ require (
github.com/gin-contrib/static v1.1.0
github.com/gin-gonic/gin v1.9.1
github.com/go-co-op/gocron/v2 v2.2.9
github.com/go-gormigrate/gormigrate/v2 v2.1.2
github.com/go-playground/validator/v10 v10.19.0
github.com/go-redis/redis/v8 v8.11.5
github.com/golang-jwt/jwt v3.2.2+incompatible
@ -35,7 +36,6 @@ require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/chenzhuoyu/iasm v0.9.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-gormigrate/gormigrate/v2 v2.1.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jonboulle/clockwork v0.4.0 // indirect

View File

@ -16,8 +16,7 @@ type Option struct {
func AllOption() ([]*Option, error) {
var options []*Option
var err error
err = DB.Find(&options).Error
err := DB.Find(&options).Error
return options, err
}
@ -83,6 +82,8 @@ func InitOptionMap() {
config.OptionMap["ChatCacheEnabled"] = strconv.FormatBool(config.ChatCacheEnabled)
config.OptionMap["ChatCacheExpireMinute"] = strconv.Itoa(config.ChatCacheExpireMinute)
config.OptionMap["ChatImageRequestProxy"] = ""
config.OptionMapRWMutex.Unlock()
loadOptionsFromDatabase()
}
@ -174,6 +175,7 @@ var optionStringMap = map[string]*string{
"ChatLinks": &config.ChatLinks,
"LarkClientId": &config.LarkClientId,
"LarkClientSecret": &config.LarkClientSecret,
"ChatImageRequestProxy": &config.ChatImageRequestProxy,
}
func updateOptionMap(key string, value string) (err error) {

View File

@ -35,7 +35,8 @@ const OperationSetting = () => {
RetryCooldownSeconds: 0,
MjNotifyEnabled: '',
ChatCacheEnabled: '',
ChatCacheExpireMinute: 5
ChatCacheExpireMinute: 5,
ChatImageRequestProxy: ''
});
const [originInputs, setOriginInputs] = useState({});
let [loading, setLoading] = useState(false);
@ -173,6 +174,9 @@ const OperationSetting = () => {
if (originInputs['ChatCacheExpireMinute'] !== inputs.ChatCacheExpireMinute) {
await updateOption('ChatCacheExpireMinute', inputs.ChatCacheExpireMinute);
}
if (originInputs['ChatImageRequestProxy'] !== inputs.ChatImageRequestProxy) {
await updateOption('ChatImageRequestProxy', inputs.ChatImageRequestProxy);
}
break;
}
@ -334,6 +338,26 @@ const OperationSetting = () => {
/>
</FormControl>
</Stack>
<Stack spacing={2}>
<Alert severity="info">
当用户使用vision模型并提供了图片链接时我们的服务器需要下载这些图片并计算 tokens为了在下载图片时保护服务器的 IP
地址不被泄露可以在下方配置一个代理这个代理配置使用的是 HTTP SOCKS5
代理如果你是个人用户这个配置可以不用理会代理格式为 http://127.0.0.1:1080 或 socks5://127.0.0.1:1080
</Alert>
<FormControl>
<InputLabel htmlFor="ChatImageRequestProxy">图片检测代理</InputLabel>
<OutlinedInput
id="ChatImageRequestProxy"
name="ChatImageRequestProxy"
value={inputs.ChatImageRequestProxy}
onChange={handleInputChange}
label="图片检测代理"
placeholder="聊天图片检测代理设置如果不设置可能会泄漏服务器ip"
disabled={loading}
/>
</FormControl>
</Stack>
<Button
variant="contained"
onClick={() => {

View File

@ -376,6 +376,9 @@ const SystemSetting = () => {
</SubCard>
<SubCard title="配置 SMTP" subTitle="用以支持系统的邮件发送">
<Grid container spacing={{ xs: 3, sm: 2, md: 4 }}>
<Grid xs={12}>
<Alert severity="info">请注意有些邮箱服务商发送邮件时会携带你的服务器IP地址非个人使用时建议使用专业的邮件服务商</Alert>
</Grid>
<Grid xs={12} md={4}>
<FormControl fullWidth>
<InputLabel htmlFor="SMTPServer">SMTP 服务器地址</InputLabel>