Add Etag for V2RaySocks (#518)

This commit is contained in:
thh1451 2023-11-11 23:21:13 +01:00 committed by GitHub
parent 6ffbe599b4
commit c170272f40
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,6 +3,7 @@ package v2raysocks
import ( import (
"bufio" "bufio"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"log" "log"
"os" "os"
@ -34,6 +35,7 @@ type APIClient struct {
LocalRuleList []api.DetectRule LocalRuleList []api.DetectRule
ConfigResp *simplejson.Json ConfigResp *simplejson.Json
access sync.Mutex access sync.Mutex
eTags map[string]string
} }
// New create an api instance // New create an api instance
@ -46,13 +48,16 @@ func New(apiConfig *api.Config) *APIClient {
} else { } else {
client.SetTimeout(5 * time.Second) client.SetTimeout(5 * time.Second)
} }
client.OnError(func(req *resty.Request, err error) { client.OnError(func(req *resty.Request, err error) {
if v, ok := err.(*resty.ResponseError); ok { var v *resty.ResponseError
if errors.As(err, &v) {
// v.Response contains the last response from the server // v.Response contains the last response from the server
// v.Err contains the original error // v.Err contains the original error
log.Print(v.Err) log.Print(v.Err)
} }
}) })
// Create Key for each requests // Create Key for each requests
client.SetQueryParams(map[string]string{ client.SetQueryParams(map[string]string{
"node_id": strconv.Itoa(apiConfig.NodeID), "node_id": strconv.Itoa(apiConfig.NodeID),
@ -71,6 +76,7 @@ func New(apiConfig *api.Config) *APIClient {
SpeedLimit: apiConfig.SpeedLimit, SpeedLimit: apiConfig.SpeedLimit,
DeviceLimit: apiConfig.DeviceLimit, DeviceLimit: apiConfig.DeviceLimit,
LocalRuleList: localRuleList, LocalRuleList: localRuleList,
eTags: make(map[string]string),
} }
return apiClient return apiClient
} }
@ -150,12 +156,22 @@ func (c *APIClient) GetNodeInfo() (nodeInfo *api.NodeInfo, err error) {
return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType) return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType)
} }
res, err := c.client.R(). res, err := c.client.R().
SetHeader("If-None-Match", c.eTags["config"]).
SetQueryParams(map[string]string{ SetQueryParams(map[string]string{
"act": "config", "act": "config",
"nodetype": nodeType, "nodetype": nodeType,
}). }).
ForceContentType("application/json"). ForceContentType("application/json").
Get(c.APIHost) Get(c.APIHost)
// 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["config"] {
c.eTags["config"] = res.Header().Get("Etag")
}
response, err := c.parseResponse(res, "", err) response, err := c.parseResponse(res, "", err)
c.access.Lock() c.access.Lock()
@ -194,12 +210,22 @@ func (c *APIClient) GetUserList() (UserList *[]api.UserInfo, err error) {
return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType) return nil, fmt.Errorf("unsupported Node type: %s", c.NodeType)
} }
res, err := c.client.R(). res, err := c.client.R().
SetHeader("If-None-Match", c.eTags["user"]).
SetQueryParams(map[string]string{ SetQueryParams(map[string]string{
"act": "user", "act": "user",
"nodetype": nodeType, "nodetype": nodeType,
}). }).
ForceContentType("application/json"). ForceContentType("application/json").
Get(c.APIHost) Get(c.APIHost)
// Etag identifier for a specific version of a resource. StatusCode = 304 means no changed
if res.StatusCode() == 304 {
return nil, errors.New(api.UserNotModified)
}
// update etag
if res.Header().Get("Etag") != "" && res.Header().Get("Etag") != c.eTags["user"] {
c.eTags["user"] = res.Header().Get("Etag")
}
response, err := c.parseResponse(res, "", err) response, err := c.parseResponse(res, "", err)
if err != nil { if err != nil {