dvc890's picture
Upload 42 files
581b6d4 verified
package common
import (
"WarpGPT/pkg/env"
"WarpGPT/pkg/logger"
"WarpGPT/pkg/plugins/service/proxypool"
"encoding/json"
browser "github.com/EDDYCJY/fake-useragent"
http "github.com/bogdanfinn/fhttp"
tls_client "github.com/bogdanfinn/tls-client"
"github.com/bogdanfinn/tls-client/profiles"
"github.com/gin-gonic/gin"
"io"
"fmt"
"math/rand"
"sync"
)
type Context struct {
GinContext *gin.Context
RequestUrl string
RequestClient tls_client.HttpClient
RequestBody io.ReadCloser
RequestParam string
RequestMethod string
RequestHeaders http.Header
}
type APIError struct {
AccessToken string
StatusCode int
}
func (e *APIError) Error() string {
return fmt.Sprintf("HTTP status %d, AccessToken: %s", e.StatusCode, e.AccessToken)
}
var tu sync.Mutex
type RequestUrl interface {
Generate(path string, rawquery string) string
}
func GetContextPack[T RequestUrl](ctx *gin.Context, reqUrl T) Context {
conversation := Context{}
conversation.GinContext = ctx
conversation.RequestUrl = reqUrl.Generate(ctx.Param("path"), ctx.Request.URL.RawQuery)
conversation.RequestMethod = ctx.Request.Method
conversation.RequestBody = ctx.Request.Body
conversation.RequestParam = ctx.Param("path")
conversation.RequestClient = GetHttpClient()
conversation.RequestHeaders = http.Header(ctx.Request.Header)
return conversation
}
func getUserAgent() string {
tu.Lock()
defer tu.Unlock()
return browser.Safari()
}
func GetHttpClient() tls_client.HttpClient {
jar := tls_client.NewCookieJar()
userAgent := map[int]profiles.ClientProfile{
1: profiles.Safari_15_6_1,
2: profiles.Safari_16_0,
3: profiles.Safari_IOS_15_5,
4: profiles.Safari_IOS_15_6,
5: profiles.Safari_IOS_16_0,
}
options := []tls_client.HttpClientOption{
tls_client.WithTimeoutSeconds(120),
tls_client.WithClientProfile(userAgent[rand.Intn(5)+1]),
tls_client.WithNotFollowRedirects(),
tls_client.WithCookieJar(jar),
tls_client.WithRandomTLSExtensionOrder(),
}
if env.E.ProxyPoolUrl != "" {
ip, err := proxypool.ProxyPoolInstance.GetIpInRedis()
if err != nil {
logger.Log.Warning(err.Error())
return nil
}
options = append(options, tls_client.WithProxyUrl(ip))
} else {
options = append(options, tls_client.WithProxyUrl(env.E.Proxy))
}
client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...)
if err != nil {
logger.Log.Error("Error creating http client:", err)
return nil
}
return client
}
func RequestOpenAI[T any](path string, body io.Reader, accessToken string, requestMethod string) (*T, error) {
url := "https://" + env.E.OpenaiHost + path
req, err := http.NewRequest(requestMethod, url, body)
if err != nil {
logger.Log.Error("Error creating request:", err)
return nil, err
}
userAgentStr := getUserAgent()
headers := map[string]string{
"Host": env.E.OpenaiHost,
"Origin": "https://" + env.E.OpenaiHost,
"Authorization": accessToken,
"Connection": "keep-alive",
"User-Agent": userAgentStr,
"Referer": "https://" + env.E.OpenaiHost,
"Content-Type": "application/json",
"Accept": "*/*",
"sec-fetch-dest": "empty",
"sec-fetch-site": "same-origin",
}
for key, value := range headers {
req.Header.Set(key, value)
}
resp, err := GetHttpClient().Do(req)
if err != nil {
logger.Log.Error("Error sending request:", err)
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
apiError := &APIError{
AccessToken: accessToken,
StatusCode: resp.StatusCode,
}
return nil, apiError
}
var data T
readAll, err := io.ReadAll(resp.Body)
if err != nil {
logger.Log.Error("Read error:", err)
return nil, err
}
if readAll == nil {
return nil, nil
}
err = json.Unmarshal(readAll, &data)
if err != nil {
logger.Log.Error("Unmarshal error:", err)
return nil, err
}
return &data, nil
}