1111
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 37s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Has been cancelled
Some checks failed
Build Multi-Platform Binaries / build-frontend (push) Successful in 37s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Has been cancelled
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Has been cancelled
This commit is contained in:
@@ -5,8 +5,8 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gotunnel/internal/server/db"
|
||||
// removed router import
|
||||
"github.com/gotunnel/internal/server/router/dto"
|
||||
"github.com/gotunnel/pkg/protocol"
|
||||
)
|
||||
|
||||
// ClientHandler 客户端处理器
|
||||
@@ -410,10 +410,14 @@ func (h *ClientHandler) deleteClientPlugin(clientID, pluginID string) error {
|
||||
}
|
||||
|
||||
var newPlugins []db.ClientPlugin
|
||||
var pluginName string
|
||||
var pluginPort int
|
||||
found := false
|
||||
for _, p := range client.Plugins {
|
||||
if p.ID == pluginID {
|
||||
found = true
|
||||
pluginName = p.Name
|
||||
pluginPort = p.RemotePort
|
||||
continue
|
||||
}
|
||||
newPlugins = append(newPlugins, p)
|
||||
@@ -423,7 +427,22 @@ func (h *ClientHandler) deleteClientPlugin(clientID, pluginID string) error {
|
||||
return fmt.Errorf("plugin %s not found", pluginID)
|
||||
}
|
||||
|
||||
// 删除插件管理的代理规则
|
||||
var newRules []protocol.ProxyRule
|
||||
for _, r := range client.Rules {
|
||||
if r.PluginManaged && r.Name == pluginName {
|
||||
continue // 跳过此插件的规则
|
||||
}
|
||||
newRules = append(newRules, r)
|
||||
}
|
||||
|
||||
// 停止端口监听器
|
||||
if pluginPort > 0 {
|
||||
h.app.GetServer().StopPluginRule(clientID, pluginPort)
|
||||
}
|
||||
|
||||
client.Plugins = newPlugins
|
||||
client.Rules = newRules
|
||||
return h.app.GetClientStore().UpdateClient(client)
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ type ServerInterface interface {
|
||||
GetClientPluginStatus(clientID string) ([]protocol.PluginStatusEntry, error)
|
||||
// 插件规则管理
|
||||
StartPluginRule(clientID string, rule protocol.ProxyRule) error
|
||||
StopPluginRule(clientID string, remotePort int) error
|
||||
// 端口检查
|
||||
IsPortAvailable(port int, excludeClientID string) bool
|
||||
// 插件 API 代理
|
||||
ProxyPluginAPIRequest(clientID string, req protocol.PluginAPIRequest) (*protocol.PluginAPIResponse, error)
|
||||
}
|
||||
|
||||
@@ -254,13 +254,19 @@ func (h *PluginHandler) UpdateClientConfig(c *gin.Context) {
|
||||
// 更新插件配置
|
||||
found := false
|
||||
portChanged := false
|
||||
var oldPort, newPort int
|
||||
for i, p := range client.Plugins {
|
||||
if p.Name == pluginName {
|
||||
oldPort = client.Plugins[i].RemotePort
|
||||
// 提取 remote_port 并单独处理
|
||||
if portStr, ok := req.Config["remote_port"]; ok {
|
||||
var newPort int
|
||||
fmt.Sscanf(portStr, "%d", &newPort)
|
||||
if newPort > 0 && newPort != client.Plugins[i].RemotePort {
|
||||
if newPort > 0 && newPort != oldPort {
|
||||
// 检查新端口是否可用
|
||||
if !h.app.GetServer().IsPortAvailable(newPort, clientID) {
|
||||
BadRequest(c, fmt.Sprintf("port %d is already in use", newPort))
|
||||
return
|
||||
}
|
||||
client.Plugins[i].RemotePort = newPort
|
||||
portChanged = true
|
||||
}
|
||||
@@ -277,6 +283,20 @@ func (h *PluginHandler) UpdateClientConfig(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果端口变更,同步更新代理规则
|
||||
if portChanged {
|
||||
for i, r := range client.Rules {
|
||||
if r.Name == pluginName && r.PluginManaged {
|
||||
client.Rules[i].RemotePort = newPort
|
||||
break
|
||||
}
|
||||
}
|
||||
// 停止旧端口监听器
|
||||
if oldPort > 0 {
|
||||
h.app.GetServer().StopPluginRule(clientID, oldPort)
|
||||
}
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
if err := h.app.GetClientStore().UpdateClient(client); err != nil {
|
||||
InternalError(c, err.Error())
|
||||
@@ -287,7 +307,6 @@ func (h *PluginHandler) UpdateClientConfig(c *gin.Context) {
|
||||
online, _, _ := h.app.GetServer().GetClientStatus(clientID)
|
||||
if online {
|
||||
if err := h.app.GetServer().SyncPluginConfigToClient(clientID, pluginName, req.Config); err != nil {
|
||||
// 配置已保存,但同步失败,返回警告
|
||||
PartialSuccess(c, gin.H{"status": "partial", "port_changed": portChanged}, "config saved but sync failed: "+err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"time"
|
||||
@@ -216,6 +217,11 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
||||
|
||||
// 自动创建代理规则(如果指定了端口)
|
||||
if req.RemotePort > 0 {
|
||||
// 检查端口是否可用
|
||||
if !h.app.GetServer().IsPortAvailable(req.RemotePort, req.ClientID) {
|
||||
InternalError(c, fmt.Sprintf("port %d is already in use", req.RemotePort))
|
||||
return
|
||||
}
|
||||
ruleExists := false
|
||||
for i, r := range dbClient.Rules {
|
||||
if r.Name == req.PluginName {
|
||||
@@ -226,6 +232,7 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
||||
dbClient.Rules[i].AuthEnabled = req.AuthEnabled
|
||||
dbClient.Rules[i].AuthUsername = req.AuthUsername
|
||||
dbClient.Rules[i].AuthPassword = req.AuthPassword
|
||||
dbClient.Rules[i].PluginManaged = true
|
||||
ruleExists = true
|
||||
break
|
||||
}
|
||||
@@ -233,13 +240,14 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
||||
if !ruleExists {
|
||||
// 创建新规则
|
||||
dbClient.Rules = append(dbClient.Rules, protocol.ProxyRule{
|
||||
Name: req.PluginName,
|
||||
Type: req.PluginName,
|
||||
RemotePort: req.RemotePort,
|
||||
Enabled: boolPtr(true),
|
||||
AuthEnabled: req.AuthEnabled,
|
||||
AuthUsername: req.AuthUsername,
|
||||
AuthPassword: req.AuthPassword,
|
||||
Name: req.PluginName,
|
||||
Type: req.PluginName,
|
||||
RemotePort: req.RemotePort,
|
||||
Enabled: boolPtr(true),
|
||||
AuthEnabled: req.AuthEnabled,
|
||||
AuthUsername: req.AuthUsername,
|
||||
AuthPassword: req.AuthPassword,
|
||||
PluginManaged: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user