mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-01-04 14:15:27 +08:00
feat: Support checking proxy server connection availability (#10502)
Refs #9843
This commit is contained in:
parent
34b39f6eb8
commit
3f141346fa
11 changed files with 78 additions and 1 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ErrHttpReqNotFound: "要求されたリソースが見つかりません {{ .err
|
|||
ErrHttpReqFailed: "リクエスト失敗 {{ .err }}"
|
||||
ErrHttpReqTimeOut: "リクエストタイムアウト {{ .err }}"
|
||||
ErrCreateHttpClient: "リクエストの作成に失敗しました {{ .err }}"
|
||||
ErrProxySetting: "プロキシサーバー情報が利用できません {{ .err }}、確認して再試行してください!"
|
||||
|
||||
# common
|
||||
ErrDemoEnvironment: "デモサーバーではこの操作は許可されていません!"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ErrHttpReqNotFound: "요청한 리소스를 찾을 수 없습니다 {{ .err }}"
|
|||
ErrHttpReqFailed: "요청 실패 {{ .err }}"
|
||||
ErrHttpReqTimeOut: "요청 시간이 초과되었습니다 {{ .err }}"
|
||||
ErrCreateHttpClient: "요청 생성 실패 {{ .err }}"
|
||||
ErrProxySetting: "프록시 서버 정보를 사용할 수 없음 {{ .err }}, 확인 후 다시 시도하세요!"
|
||||
|
||||
# common
|
||||
ErrDemoEnvironment: "데모 서버에서는 이 작업이 금지되어 있습니다!"
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ErrHttpReqNotFound: "Не удалось найти запрашиваемый
|
|||
ErrHttpReqFailed: "Ошибка запроса {{ .err }}"
|
||||
ErrHttpReqTimeOut: "Время ожидания запроса истекло {{ .err }}"
|
||||
ErrCreateHttpClient: "Ошибка создания запроса {{ .err }}"
|
||||
ErrProxySetting: "Информация о прокси-сервере недоступна {{ .err }}, проверьте и повторите попытку!"
|
||||
|
||||
# common
|
||||
ErrDemoEnvironment: "Демонстрационный сервер, эта операция запрещена!"
|
||||
|
|
|
|||
|
|
@ -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!"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ErrHttpReqNotFound: "無法找到請求的資源 {{ .err }}"
|
|||
ErrHttpReqFailed: "請求失敗 {{ .err }}"
|
||||
ErrHttpReqTimeOut: "請求逾時 {{ .err }}"
|
||||
ErrCreateHttpClient: "建立請求失敗 {{ .err }}"
|
||||
ErrProxySetting: "代理伺服器資訊不可用 {{ .err }},請檢查後重試!"
|
||||
|
||||
#common
|
||||
ErrDemoEnvironment: "示範伺服器,禁止此操作!"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ ErrHttpReqNotFound: "无法找到请求的资源 {{ .err }}"
|
|||
ErrHttpReqFailed: "请求失败 {{ .err }}"
|
||||
ErrHttpReqTimeOut: "请求超时 {{ .err }}"
|
||||
ErrCreateHttpClient: "创建请求失败 {{ .err }}"
|
||||
ErrProxySetting: "代理服务器信息不可用 {{ .err }},请检查后重试!"
|
||||
|
||||
#common
|
||||
ErrDemoEnvironment: "演示服务器,禁止此操作!"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue