From f6b587b275b4546590531360676f98ac997d48e0 Mon Sep 17 00:00:00 2001 From: wyx2685 Date: Fri, 4 Jul 2025 11:37:23 +0900 Subject: [PATCH] prefer msgpack for userlist --- api/panel/user.go | 32 +++++++++++++++++++++++--------- go.mod | 3 +++ go.sum | 4 ++++ 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/api/panel/user.go b/api/panel/user.go index c13d49c..1bf6ab6 100644 --- a/api/panel/user.go +++ b/api/panel/user.go @@ -2,8 +2,11 @@ package panel import ( "fmt" + "io" + "strings" "github.com/goccy/go-json" + "github.com/vmihailenco/msgpack" ) type OnlineUser struct { @@ -12,15 +15,14 @@ type OnlineUser struct { } type UserInfo struct { - Id int `json:"id"` - Uuid string `json:"uuid"` - SpeedLimit int `json:"speed_limit"` - DeviceLimit int `json:"device_limit"` + Id int `json:"id" msgpack:"id"` + Uuid string `json:"uuid" msgpack:"uuid"` + SpeedLimit int `json:"speed_limit" msgpack:"speed_limit"` + DeviceLimit int `json:"device_limit" msgpack:"device_limit"` } type UserListBody struct { - //Msg string `json:"msg"` - Users []UserInfo `json:"users"` + Users []UserInfo `json:"users" msgpack:"users"` } type AliveMap struct { @@ -32,7 +34,8 @@ func (c *Client) GetUserList() ([]UserInfo, error) { const path = "/api/v1/server/UniProxy/user" r, err := c.client.R(). SetHeader("If-None-Match", c.userEtag). - ForceContentType("application/json"). + SetHeader("X-Response-Format", "msgpack"). + SetDoNotParseResponse(true). Get(path) if r == nil || r.RawResponse == nil { return nil, fmt.Errorf("received nil response or raw response") @@ -47,8 +50,19 @@ func (c *Client) GetUserList() ([]UserInfo, error) { return nil, err } userlist := &UserListBody{} - if err := json.Unmarshal(r.Body(), userlist); err != nil { - return nil, fmt.Errorf("unmarshal user list error: %w", err) + if strings.Contains(r.Header().Get("Content-Type"), "application/x-msgpack") { + decoder := msgpack.NewDecoder(r.RawResponse.Body) + if err := decoder.Decode(userlist); err != nil { + return nil, fmt.Errorf("decode user list error: %w", err) + } + } else { + bodyBytes, err := io.ReadAll(r.RawResponse.Body) + if err != nil { + return nil, fmt.Errorf("read response body error: %w", err) + } + if err := json.Unmarshal(bodyBytes, userlist); err != nil { + return nil, fmt.Errorf("unmarshal user list error: %w", err) + } } c.userEtag = r.Header().Get("ETag") return userlist.Users, nil diff --git a/go.mod b/go.mod index 306b8aa..ce32c40 100644 --- a/go.mod +++ b/go.mod @@ -20,6 +20,7 @@ require ( github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.9.1 github.com/spf13/viper v1.19.0 + github.com/vmihailenco/msgpack v4.0.4+incompatible github.com/xtls/xray-core v1.250516.1-0.20250608135303-fbae89d017ae go.uber.org/zap v1.27.0 golang.org/x/crypto v0.39.0 @@ -124,6 +125,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.1 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.1.0 // indirect @@ -314,6 +316,7 @@ require ( golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect google.golang.org/api v0.214.0 // indirect + google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect diff --git a/go.sum b/go.sum index 041df0a..6b91853 100644 --- a/go.sum +++ b/go.sum @@ -1086,6 +1086,8 @@ github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5J github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY= github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= +github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/volcengine/volc-sdk-golang v1.0.189 h1:VMDTHWYXakXJtZqPYn0As/h4eB0c4imvyru6mIp+o60= github.com/volcengine/volc-sdk-golang v1.0.189/go.mod h1:u0VtPvlXWpXDTmc9IHkaW1q+5Jjwus4oAqRhNMDRInE= github.com/vultr/govultr/v3 v3.9.1 h1:uxSIb8Miel7tqTs3ee+z3t+JelZikwqBBsZzCOPBy/8= @@ -1548,6 +1550,8 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=