diff --git a/core/app/service/setting.go b/core/app/service/setting.go index 813479012..7ef7187de 100644 --- a/core/app/service/setting.go +++ b/core/app/service/setting.go @@ -2,6 +2,7 @@ package service import ( "bytes" + "context" "crypto/rand" "crypto/rsa" "crypto/tls" @@ -9,8 +10,10 @@ import ( "encoding/json" "encoding/pem" "fmt" + "io" "net" "net/http" + "net/url" "os" "path" "strconv" @@ -30,6 +33,7 @@ import ( "github.com/1Panel-dev/1Panel/core/utils/req_helper/proxy_local" "github.com/1Panel-dev/1Panel/core/utils/xpack" "github.com/gin-gonic/gin" + "golang.org/x/net/proxy" ) type SettingService struct{} @@ -38,7 +42,6 @@ type ISettingService interface { GetSettingInfo() (*dto.SettingInfo, error) LoadInterfaceAddr() ([]string, error) Update(key, value string) error - UpdateProxy(req dto.ProxyUpdate) error UpdatePassword(c *gin.Context, old, new string) error UpdatePort(port uint) error UpdateBindInfo(req dto.BindInfo) error @@ -48,6 +51,8 @@ type ISettingService interface { GenerateApiKey() (string, error) UpdateApiConfig(req dto.ApiInterfaceConfig) error + UpdateProxy(req dto.ProxyUpdate) error + GetTerminalInfo() (*dto.TerminalInfo, error) UpdateTerminal(req dto.TerminalInfo) error @@ -192,6 +197,10 @@ func (u *SettingService) UpdateProxy(req dto.ProxyUpdate) error { proxyUrl := req.ProxyUrl if req.ProxyType == "https" || req.ProxyType == "http" { proxyUrl = req.ProxyType + "://" + req.ProxyUrl + req.ProxyUrl = proxyUrl + } + if err := checkProxy(req); err != nil { + return err } if err := settingRepo.Update("ProxyUrl", proxyUrl); err != nil { return err @@ -691,3 +700,61 @@ func loadDockerProxy(req dto.ProxyUpdate) string { return fmt.Sprintf("%s://%s%s:%s", req.ProxyType, account, req.ProxyUrl, req.ProxyPort) } + +func checkProxy(req dto.ProxyUpdate) error { + var transport http.Transport + proxyItem := net.JoinHostPort(req.ProxyUrl, req.ProxyPort) + switch req.ProxyType { + case "http", "https": + proxyURL, err := url.Parse(proxyItem) + if err != nil { + return buserr.WithErr("ErrProxySetting", fmt.Errorf("parse url %s failed, err: %v", proxyItem, err)) + } + if len(req.ProxyUser) != 0 { + proxyURL.User = url.UserPassword(req.ProxyUser, req.ProxyPasswd) + } + transport = http.Transport{Proxy: http.ProxyURL(proxyURL)} + case "socks5": + var auth *proxy.Auth + if len(req.ProxyUser) == 0 { + auth = nil + } else { + auth = &proxy.Auth{User: req.ProxyUser, Password: req.ProxyPasswd} + } + dialer, err := proxy.SOCKS5("tcp", proxyItem, auth, proxy.Direct) + if err != nil { + return buserr.WithErr("ErrProxySetting", fmt.Errorf("new socks5 proxy failed, err: %v", err)) + } + dialContext := func(ctx context.Context, network, addr string) (net.Conn, error) { + return dialer.Dial(network, addr) + } + transport = http.Transport{DialContext: dialContext} + case "", "close": + default: + return buserr.WithDetail("ErrNotSupportType", req.ProxyType, nil) + } + defer func() { + if r := recover(); r != nil { + global.LOG.Errorf("handle request failed, error message: %v", r) + return + } + }() + + client := http.Client{Timeout: 3 * time.Second, Transport: &transport} + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + request, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://1panel.cn/", nil) + if err != nil { + return buserr.WithErr("ErrProxySetting", err) + } + request.Header.Set("Content-Type", "application/json") + resp, err := client.Do(request) + if err != nil { + return buserr.WithErr("ErrProxySetting", err) + } + if _, err := io.ReadAll(resp.Body); err != nil { + return buserr.WithErr("ErrProxySetting", err) + } + defer resp.Body.Close() + return nil +} diff --git a/core/i18n/lang/en.yaml b/core/i18n/lang/en.yaml index 0d4248920..e4c3f69ef 100644 --- a/core/i18n/lang/en.yaml +++ b/core/i18n/lang/en.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "Unable to find the requested resource {{ .err }}" ErrHttpReqFailed: "Request failed {{ .err }}" ErrHttpReqTimeOut: "Request timed out {{ .err }}" ErrCreateHttpClient: "Failed to create request {{ .err }}" +ErrProxySetting: "Proxy server information unavailable {{ .err }}, please check and try again!" # common ErrDemoEnvironment: "Demo server, this operation is prohibited!" diff --git a/core/i18n/lang/es-ES.yaml b/core/i18n/lang/es-ES.yaml index c2410f3e5..d2a455e20 100644 --- a/core/i18n/lang/es-ES.yaml +++ b/core/i18n/lang/es-ES.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "No se pudo encontrar el recurso solicitado {{ .err }}" ErrHttpReqFailed: "Solicitud fallida {{ .err }}" ErrHttpReqTimeOut: "La solicitud ha expirado {{ .err }}" ErrCreateHttpClient: "Error al crear la solicitud {{ .err }}" +ErrProxySetting: "Información del servidor proxy no disponible {{ .err }}, ¡compruebe e inténtelo de nuevo!" # common ErrDemoEnvironment: "Servidor de demostración, ¡esta operación está prohibida!" diff --git a/core/i18n/lang/ja.yaml b/core/i18n/lang/ja.yaml index 1da18ad60..d64f34023 100644 --- a/core/i18n/lang/ja.yaml +++ b/core/i18n/lang/ja.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "要求されたリソースが見つかりません {{ .err ErrHttpReqFailed: "リクエスト失敗 {{ .err }}" ErrHttpReqTimeOut: "リクエストタイムアウト {{ .err }}" ErrCreateHttpClient: "リクエストの作成に失敗しました {{ .err }}" +ErrProxySetting: "プロキシサーバー情報が利用できません {{ .err }}、確認して再試行してください!" # common ErrDemoEnvironment: "デモサーバーではこの操作は許可されていません!" diff --git a/core/i18n/lang/ko.yaml b/core/i18n/lang/ko.yaml index 6028dad06..4250775a0 100644 --- a/core/i18n/lang/ko.yaml +++ b/core/i18n/lang/ko.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "요청한 리소스를 찾을 수 없습니다 {{ .err }}" ErrHttpReqFailed: "요청 실패 {{ .err }}" ErrHttpReqTimeOut: "요청 시간이 초과되었습니다 {{ .err }}" ErrCreateHttpClient: "요청 생성 실패 {{ .err }}" +ErrProxySetting: "프록시 서버 정보를 사용할 수 없음 {{ .err }}, 확인 후 다시 시도하세요!" # common ErrDemoEnvironment: "데모 서버에서는 이 작업이 금지되어 있습니다!" diff --git a/core/i18n/lang/ms.yml b/core/i18n/lang/ms.yml index 979e7688f..56ae240e4 100644 --- a/core/i18n/lang/ms.yml +++ b/core/i18n/lang/ms.yml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "Sumber yang diminta tidak dapat ditemui {{ .err }}" ErrHttpReqFailed: "Permintaan gagal {{ .err }}" ErrHttpReqTimeOut: "Permintaan telah tamat masa {{ .err }}" ErrCreateHttpClient: "Gagal mencipta permintaan {{ .err }}" +ErrProxySetting: "Maklumat pelayan proksi tidak tersedia {{ .err }}, sila periksa dan cuba lagi!" # common ErrDemoEnvironment: "Pelayan demo, operasi ini dilarang!" diff --git a/core/i18n/lang/pt-BR.yaml b/core/i18n/lang/pt-BR.yaml index 26b6e86ae..4dba30ec6 100644 --- a/core/i18n/lang/pt-BR.yaml +++ b/core/i18n/lang/pt-BR.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "Recurso solicitado não encontrado {{ .err }}" ErrHttpReqFailed: "Falha na requisição {{ .err }}" ErrHttpReqTimeOut: "Tempo de requisição esgotado {{ .err }}" ErrCreateHttpClient: "Falha ao criar a requisição {{ .err }}" +ErrProxySetting: "Informação do servidor proxy indisponível {{ .err }}, verifique e tente novamente!" # common ErrDemoEnvironment: "Servidor de demonstração, essa operação é proibida!" diff --git a/core/i18n/lang/ru.yaml b/core/i18n/lang/ru.yaml index 9e01640aa..c7a4d4ec4 100644 --- a/core/i18n/lang/ru.yaml +++ b/core/i18n/lang/ru.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "Не удалось найти запрашиваемый ErrHttpReqFailed: "Ошибка запроса {{ .err }}" ErrHttpReqTimeOut: "Время ожидания запроса истекло {{ .err }}" ErrCreateHttpClient: "Ошибка создания запроса {{ .err }}" +ErrProxySetting: "Информация о прокси-сервере недоступна {{ .err }}, проверьте и повторите попытку!" # common ErrDemoEnvironment: "Демонстрационный сервер, эта операция запрещена!" diff --git a/core/i18n/lang/tr.yaml b/core/i18n/lang/tr.yaml index bcc424723..b8a15520e 100644 --- a/core/i18n/lang/tr.yaml +++ b/core/i18n/lang/tr.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "İstenen kaynak bulunamıyor {{ .err }}" ErrHttpReqFailed: "İstek başarısız {{ .err }}" ErrHttpReqTimeOut: "İstek zaman aşımına uğradı {{ .err }}" ErrCreateHttpClient: "İstek oluşturma başarısız {{ .err }}" +ErrProxySetting: "Proxy sunucu bilgisi kullanılamıyor {{ .err }}, lütfen kontrol edip tekrar deneyin!" # common ErrDemoEnvironment: "Demo sunucu, bu işlem yasak!" diff --git a/core/i18n/lang/zh-Hant.yaml b/core/i18n/lang/zh-Hant.yaml index a6b8a14fc..acffaa322 100644 --- a/core/i18n/lang/zh-Hant.yaml +++ b/core/i18n/lang/zh-Hant.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "無法找到請求的資源 {{ .err }}" ErrHttpReqFailed: "請求失敗 {{ .err }}" ErrHttpReqTimeOut: "請求逾時 {{ .err }}" ErrCreateHttpClient: "建立請求失敗 {{ .err }}" +ErrProxySetting: "代理伺服器資訊不可用 {{ .err }},請檢查後重試!" #common ErrDemoEnvironment: "示範伺服器,禁止此操作!" diff --git a/core/i18n/lang/zh.yaml b/core/i18n/lang/zh.yaml index 1e5f1882e..b74b156e1 100644 --- a/core/i18n/lang/zh.yaml +++ b/core/i18n/lang/zh.yaml @@ -21,6 +21,7 @@ ErrHttpReqNotFound: "无法找到请求的资源 {{ .err }}" ErrHttpReqFailed: "请求失败 {{ .err }}" ErrHttpReqTimeOut: "请求超时 {{ .err }}" ErrCreateHttpClient: "创建请求失败 {{ .err }}" +ErrProxySetting: "代理服务器信息不可用 {{ .err }},请检查后重试!" #common ErrDemoEnvironment: "演示服务器,禁止此操作!"