From f78de5833710abb0f58aedccc79dfdf57799048b Mon Sep 17 00:00:00 2001 From: Vincent Young Date: Tue, 18 Jun 2024 04:09:20 +0900 Subject: [PATCH] feat: support http proxy (#119) --- config.go | 10 +++++++- main.go | 29 +++++++++++++++++---- translate.go | 71 ++++++++++++++++++++++++++++++++++++++++++---------- types.go | 3 ++- 4 files changed, 93 insertions(+), 20 deletions(-) diff --git a/config.go b/config.go index 13139e7a..b2ccb24e 100644 --- a/config.go +++ b/config.go @@ -2,7 +2,7 @@ * @Author: Vincent Yang * @Date: 2024-04-23 00:39:03 * @LastEditors: Vincent Yang - * @LastEditTime: 2024-04-23 00:43:43 + * @LastEditTime: 2024-06-18 02:40:52 * @FilePath: /DeepLX/config.go * @Telegram: https://t.me/missuo * @GitHub: https://github.com/missuo @@ -50,6 +50,14 @@ func initConfig() *Config { } } + // HTTP Proxy flag + flag.StringVar(&cfg.Proxy, "proxy", "", "set the proxy URL for HTTP requests") + if cfg.Proxy == "" { + if proxy, ok := os.LookupEnv("PROXY"); ok { + cfg.Proxy = proxy + } + } + flag.Parse() return cfg } diff --git a/main.go b/main.go index 55bfd3b0..7d4af497 100644 --- a/main.go +++ b/main.go @@ -1,8 +1,8 @@ /* * @Author: Vincent Yang * @Date: 2023-07-01 21:45:34 - * @LastEditors: Vincent Young - * @LastEditTime: 2024-04-23 14:49:35 + * @LastEditors: Vincent Yang + * @LastEditTime: 2024-06-18 02:41:55 * @FilePath: /DeepLX/main.go * @Telegram: https://t.me/missuo * @GitHub: https://github.com/missuo @@ -15,6 +15,7 @@ import ( "fmt" "log" "net/http" + "net/url" "os" "strings" @@ -62,6 +63,21 @@ func main() { fmt.Printf("DeepL X has been successfully launched! Listening on 0.0.0.0:%v\n", cfg.Port) fmt.Println("Developed by sjlleo and missuo .") + // Set Proxy + proxyURL := os.Getenv("PROXY") + if proxyURL == "" { + proxyURL = cfg.Proxy + } + if proxyURL != "" { + proxy, err := url.Parse(proxyURL) + if err != nil { + log.Fatalf("Failed to parse proxy URL: %v", err) + } + http.DefaultTransport = &http.Transport{ + Proxy: http.ProxyURL(proxy), + } + } + if cfg.Token != "" { fmt.Println("Access token is set.") } @@ -91,8 +107,9 @@ func main() { targetLang := req.TargetLang translateText := req.TransText authKey := cfg.AuthKey + proxyURL := cfg.Proxy - result, err := translateByDeepLX(sourceLang, targetLang, translateText, authKey) + result, err := translateByDeepLX(sourceLang, targetLang, translateText, authKey, proxyURL) if err != nil { log.Fatalf("Translation failed: %s", err) } @@ -124,6 +141,7 @@ func main() { sourceLang := req.SourceLang targetLang := req.TargetLang translateText := req.TransText + proxyURL := cfg.Proxy dlSession := cfg.DlSession @@ -146,7 +164,7 @@ func main() { return } - result, err := translateByDeepLXPro(sourceLang, targetLang, translateText, dlSession) + result, err := translateByDeepLXPro(sourceLang, targetLang, translateText, dlSession, proxyURL) if err != nil { log.Fatalf("Translation failed: %s", err) } @@ -174,6 +192,7 @@ func main() { r.POST("/v2/translate", authMiddleware(cfg), func(c *gin.Context) { authorizationHeader := c.GetHeader("Authorization") var authKey string + proxyURL := cfg.Proxy if strings.HasPrefix(authorizationHeader, "DeepL-Auth-Key") { parts := strings.Split(authorizationHeader, " ") @@ -206,7 +225,7 @@ func main() { targetLang = jsonData.TargetLang } - result, err := translateByDeepLX("", targetLang, translateText, authKey) + result, err := translateByDeepLX("", targetLang, translateText, authKey, proxyURL) if err != nil { log.Fatalf("Translation failed: %s", err) } diff --git a/translate.go b/translate.go index 44e022a4..4b1e57c1 100644 --- a/translate.go +++ b/translate.go @@ -6,6 +6,7 @@ import ( "io" "log" "net/http" + "net/url" "strings" "github.com/abadojack/whatlanggo" @@ -46,8 +47,8 @@ func initDeepLXData(sourceLang string, targetLang string) *PostData { } } -func translateByOfficialAPI(text string, sourceLang string, targetLang string, authKey string) (string, error) { - url := "https://api-free.deepl.com/v2/translate" +func translateByOfficialAPI(text string, sourceLang string, targetLang string, authKey string, proxyURL string) (string, error) { + freeURL := "https://api-free.deepl.com/v2/translate" textArray := strings.Split(text, "\n") payload := PayloadAPI{ @@ -61,7 +62,7 @@ func translateByOfficialAPI(text string, sourceLang string, targetLang string, a return "", err } - req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes)) + req, err := http.NewRequest("POST", freeURL, bytes.NewBuffer(payloadBytes)) if err != nil { return "", err } @@ -69,7 +70,20 @@ func translateByOfficialAPI(text string, sourceLang string, targetLang string, a req.Header.Set("Authorization", "DeepL-Auth-Key "+authKey) req.Header.Set("Content-Type", "application/json") - client := &http.Client{} + var client *http.Client + if proxyURL != "" { + proxy, err := url.Parse(proxyURL) + if err != nil { + return "", err + } + transport := &http.Transport{ + Proxy: http.ProxyURL(proxy), + } + client = &http.Client{Transport: transport} + } else { + client = &http.Client{} + } + resp, err := client.Do(req) if err != nil { return "", err @@ -97,7 +111,7 @@ func translateByOfficialAPI(text string, sourceLang string, targetLang string, a return sb.String(), nil } -func translateByDeepLX(sourceLang string, targetLang string, translateText string, authKey string) (DeepLXTranslationResult, error) { +func translateByDeepLX(sourceLang string, targetLang string, translateText string, authKey string, proxyURL string) (DeepLXTranslationResult, error) { id := getRandomNumber() if sourceLang == "" { lang := whatlanggo.DetectLang(translateText) @@ -117,7 +131,7 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin } // Preparing the request data for the DeepL API - url := "https://www2.deepl.com/jsonrpc" + www2URL := "https://www2.deepl.com/jsonrpc" id = id + 1 postData := initDeepLXData(sourceLang, targetLang) text := Text{ @@ -142,7 +156,7 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin // Creating a new HTTP POST request with the JSON data as the body post_byte = []byte(postStr) reader := bytes.NewReader(post_byte) - request, err := http.NewRequest("POST", url, reader) + request, err := http.NewRequest("POST", www2URL, reader) if err != nil { log.Println(err) @@ -166,7 +180,23 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin request.Header.Set("Connection", "keep-alive") // Making the HTTP request to the DeepL API - client := &http.Client{} + var client *http.Client + if proxyURL != "" { + proxy, err := url.Parse(proxyURL) + if err != nil { + return DeepLXTranslationResult{ + Code: http.StatusServiceUnavailable, + Message: "Uknown error", + }, nil + } + transport := &http.Transport{ + Proxy: http.ProxyURL(proxy), + } + client = &http.Client{Transport: transport} + } else { + client = &http.Client{} + } + resp, err := client.Do(request) if err != nil { log.Println(err) @@ -208,7 +238,7 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin continue } else { if validity { - translatedText, err := translateByOfficialAPI(translateText, sourceLang, targetLang, authKey) + translatedText, err := translateByOfficialAPI(translateText, sourceLang, targetLang, authKey, proxyURL) if err != nil { return DeepLXTranslationResult{ Code: http.StatusTooManyRequests, @@ -258,7 +288,7 @@ func translateByDeepLX(sourceLang string, targetLang string, translateText strin }, nil } -func translateByDeepLXPro(sourceLang string, targetLang string, translateText string, dlSession string) (DeepLXTranslationResult, error) { +func translateByDeepLXPro(sourceLang string, targetLang string, translateText string, dlSession string, proxyURL string) (DeepLXTranslationResult, error) { id := getRandomNumber() if sourceLang == "" { lang := whatlanggo.DetectLang(translateText) @@ -278,7 +308,7 @@ func translateByDeepLXPro(sourceLang string, targetLang string, translateText st } // Preparing the request data for the DeepL API - url := "https://api.deepl.com/jsonrpc" + proURL := "https://api.deepl.com/jsonrpc" id = id + 1 postData := initDeepLXData(sourceLang, targetLang) text := Text{ @@ -303,7 +333,7 @@ func translateByDeepLXPro(sourceLang string, targetLang string, translateText st // Creating a new HTTP POST request with the JSON data as the body post_byte = []byte(postStr) reader := bytes.NewReader(post_byte) - request, err := http.NewRequest("POST", url, reader) + request, err := http.NewRequest("POST", proURL, reader) if err != nil { log.Println(err) @@ -324,7 +354,22 @@ func translateByDeepLXPro(sourceLang string, targetLang string, translateText st request.Header.Set("Cookie", "dl_session="+dlSession) // Making the HTTP request to the DeepL API - client := &http.Client{} + var client *http.Client + if proxyURL != "" { + proxy, err := url.Parse(proxyURL) + if err != nil { + return DeepLXTranslationResult{ + Code: http.StatusServiceUnavailable, + Message: "DeepL API request failed", + }, nil + } + transport := &http.Transport{ + Proxy: http.ProxyURL(proxy), + } + client = &http.Client{Transport: transport} + } else { + client = &http.Client{} + } resp, err := client.Do(request) if err != nil { log.Println(err) diff --git a/types.go b/types.go index b81eb0ad..9e9e2b73 100644 --- a/types.go +++ b/types.go @@ -2,7 +2,7 @@ * @Author: Vincent Yang * @Date: 2024-03-20 15:43:57 * @LastEditors: Vincent Yang - * @LastEditTime: 2024-04-23 00:37:39 + * @LastEditTime: 2024-06-18 02:38:48 * @FilePath: /DeepLX/types.go * @Telegram: https://t.me/missuo * @GitHub: https://github.com/missuo @@ -16,6 +16,7 @@ type Config struct { Token string AuthKey string DlSession string + Proxy string } type Lang struct {