From 42da6c155df34cb2af1141811ea4890e8be2b04f Mon Sep 17 00:00:00 2001 From: Senis John Date: Sun, 11 Jun 2023 20:07:43 +0800 Subject: [PATCH] fix: unexceptional etags handle --- api/apimodel.go | 6 +++ api/newV2board/v2board.go | 21 +++++++--- api/sspanel/sspanel.go | 28 +++++++------- main/main.go | 2 +- service/controller/controller.go | 66 +++++++++++++++++--------------- 5 files changed, 72 insertions(+), 51 deletions(-) diff --git a/api/apimodel.go b/api/apimodel.go index 7236b86..7b89da3 100644 --- a/api/apimodel.go +++ b/api/apimodel.go @@ -7,6 +7,12 @@ import ( "github.com/xtls/xray-core/infra/conf" ) +const ( + UserNotModified = "users not modified" + NodeNotModified = "node not modified" + RuleNotModified = "rules not modified" +) + // Config API config type Config struct { APIHost string `mapstructure:"ApiHost"` diff --git a/api/newV2board/v2board.go b/api/newV2board/v2board.go index 0929ad5..ad5bfb1 100644 --- a/api/newV2board/v2board.go +++ b/api/newV2board/v2board.go @@ -34,7 +34,7 @@ type APIClient struct { DeviceLimit int LocalRuleList []api.DetectRule resp atomic.Value - eTag string + eTags map[string]string } // New create an api instance @@ -73,6 +73,7 @@ func New(apiConfig *api.Config) *APIClient { SpeedLimit: apiConfig.SpeedLimit, DeviceLimit: apiConfig.DeviceLimit, LocalRuleList: localRuleList, + eTags: make(map[string]string), } return apiClient } @@ -147,9 +148,19 @@ func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) { path := "/api/v1/server/UniProxy/config" res, err := c.client.R(). + SetHeader("If-None-Match", c.eTags["node"]). ForceContentType("application/json"). Get(path) + // Etag identifier for a specific version of a resource. StatusCode = 304 means no changed + if res.StatusCode() == 304 { + return nil, errors.New(api.NodeNotModified) + } + // update etag + if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTags["node"] { + c.eTags["node"] = res.Header().Get("Etag") + } + nodeInfoResp, err := c.parseResponse(res, path, err) if err != nil { return nil, err @@ -194,17 +205,17 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) { } res, err := c.client.R(). - SetHeader("If-None-Match", c.eTag). + SetHeader("If-None-Match", c.eTags["users"]). ForceContentType("application/json"). Get(path) // Etag identifier for a specific version of a resource. StatusCode = 304 means no changed if res.StatusCode() == 304 { - return nil, errors.New("users no change") + return nil, errors.New(api.UserNotModified) } // update etag - if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTag { - c.eTag = res.Header().Get("Etag") + if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTags["users"] { + c.eTags["users"] = res.Header().Get("Etag") } usersResp, err := c.parseResponse(res, path, err) diff --git a/api/sspanel/sspanel.go b/api/sspanel/sspanel.go index f42b073..cc74a08 100644 --- a/api/sspanel/sspanel.go +++ b/api/sspanel/sspanel.go @@ -41,7 +41,7 @@ type APIClient struct { LastReportOnline map[int]int access sync.Mutex version string - eTag map[string]string + eTags map[string]string } // New creat a api instance @@ -82,7 +82,7 @@ func New(apiConfig *api.Config) *APIClient { LocalRuleList: localRuleList, DisableCustomConfig: apiConfig.DisableCustomConfig, LastReportOnline: make(map[int]int), - eTag: make(map[string]string), + eTags: make(map[string]string), } } @@ -158,16 +158,16 @@ func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) { path := fmt.Sprintf("/mod_mu/nodes/%d/info", c.NodeID) res, err := c.client.R(). SetResult(&Response{}). - SetHeader("If-None-Match", c.eTag["NodeInfo"]). + SetHeader("If-None-Match", c.eTags["node"]). ForceContentType("application/json"). Get(path) // Etag identifier for a specific version of a resource. StatusCode = 304 means no changed if res.StatusCode() == 304 { - return nil, errors.New("NodeInfo no change") + return nil, errors.New(api.NodeNotModified) } - if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTag["NodeInfo"] { - c.eTag["NodeInfo"] = res.Header().Get("ETag") + if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTags["node"] { + c.eTags["node"] = res.Header().Get("ETag") } response, err := c.parseResponse(res, path, err) @@ -228,17 +228,17 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) { path := "/mod_mu/users" res, err := c.client.R(). SetQueryParam("node_id", strconv.Itoa(c.NodeID)). - SetHeader("If-None-Match", c.eTag["UserList"]). + SetHeader("If-None-Match", c.eTags["users"]). SetResult(&Response{}). ForceContentType("application/json"). Get(path) // Etag identifier for a specific version of a resource. StatusCode = 304 means no changed if res.StatusCode() == 304 { - return nil, errors.New("users no change") + return nil, errors.New(api.UserNotModified) } - if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTag["UserList"] { - c.eTag["UserList"] = res.Header().Get("ETag") + if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTags["users"] { + c.eTags["users"] = res.Header().Get("ETag") } response, err := c.parseResponse(res, path, err) @@ -349,17 +349,17 @@ func (c *APIClient) GetNodeRule() (*[]api.DetectRule, error) { path := "/mod_mu/func/detect_rules" res, err := c.client.R(). SetResult(&Response{}). - SetHeader("If-None-Match", c.eTag["NodeRule"]). + SetHeader("If-None-Match", c.eTags["rules"]). ForceContentType("application/json"). Get(path) // Etag identifier for a specific version of a resource. StatusCode = 304 means no changed if res.StatusCode() == 304 { - return nil, errors.New("detect_rules no change") + return nil, errors.New(api.RuleNotModified) } - if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTag["NodeRule"] { - c.eTag["NodeRule"] = res.Header().Get("ETag") + if res.Header().Get("ETag") != "" && res.Header().Get("ETag") != c.eTags["rules"] { + c.eTags["rules"] = res.Header().Get("ETag") } response, err := c.parseResponse(res, path, err) diff --git a/main/main.go b/main/main.go index 8e7b66d..eac73d8 100644 --- a/main/main.go +++ b/main/main.go @@ -24,7 +24,7 @@ var ( ) var ( - version = "0.9.0" + version = "0.9.1" codename = "XrayR" intro = "A Xray backend that supports many panels" ) diff --git a/service/controller/controller.go b/service/controller/controller.go index 5151893..e156ff6 100644 --- a/service/controller/controller.go +++ b/service/controller/controller.go @@ -185,7 +185,7 @@ func (c *Controller) nodeInfoMonitor() (err error) { var nodeInfoChanged = true newNodeInfo, err := c.apiClient.GetNodeInfo() if err != nil { - if err.Error() == "NodeInfo no change" { + if err.Error() == api.NodeNotModified { nodeInfoChanged = false newNodeInfo = c.nodeInfo } else { @@ -201,7 +201,7 @@ func (c *Controller) nodeInfoMonitor() (err error) { var usersChanged = true newUserInfo, err := c.apiClient.GetUserList() if err != nil { - if err.Error() == "users no change" { + if err.Error() == api.UserNotModified { usersChanged = false newUserInfo = c.userList } else { @@ -211,41 +211,45 @@ func (c *Controller) nodeInfoMonitor() (err error) { } // If nodeInfo changed - if nodeInfoChanged && !reflect.DeepEqual(c.nodeInfo, newNodeInfo) { - // Remove old tag - oldTag := c.Tag - err := c.removeOldTag(oldTag) - if err != nil { - log.Print(err) - return nil - } - if c.nodeInfo.NodeType == "Shadowsocks-Plugin" { - err = c.removeOldTag(fmt.Sprintf("dokodemo-door_%s+1", c.Tag)) - } - if err != nil { - log.Print(err) - return nil - } - // Add new tag - c.nodeInfo = newNodeInfo - c.Tag = c.buildNodeTag() - err = c.addNewTag(newNodeInfo) - if err != nil { - log.Print(err) - return nil - } - nodeInfoChanged = true - // Remove Old limiter - if err = c.DeleteInboundLimiter(oldTag); err != nil { - log.Print(err) - return nil + if nodeInfoChanged { + if !reflect.DeepEqual(c.nodeInfo, newNodeInfo) { + // Remove old tag + oldTag := c.Tag + err := c.removeOldTag(oldTag) + if err != nil { + log.Print(err) + return nil + } + if c.nodeInfo.NodeType == "Shadowsocks-Plugin" { + err = c.removeOldTag(fmt.Sprintf("dokodemo-door_%s+1", c.Tag)) + } + if err != nil { + log.Print(err) + return nil + } + // Add new tag + c.nodeInfo = newNodeInfo + c.Tag = c.buildNodeTag() + err = c.addNewTag(newNodeInfo) + if err != nil { + log.Print(err) + return nil + } + nodeInfoChanged = true + // Remove Old limiter + if err = c.DeleteInboundLimiter(oldTag); err != nil { + log.Print(err) + return nil + } + } else { + nodeInfoChanged = false } } // Check Rule if !c.config.DisableGetRule { if ruleList, err := c.apiClient.GetNodeRule(); err != nil { - if err.Error() != "detect_rules no change" { + if err.Error() != api.RuleNotModified { log.Printf("Get rule list filed: %s", err) } } else if len(*ruleList) > 0 {