GET类型通道创建端点;修改完善返回格式处理逻辑;动态刷新remote令牌

This commit is contained in:
2025-04-02 16:08:55 +08:00
parent 1b8e118fae
commit 13794c2d27
12 changed files with 639 additions and 673 deletions

View File

@@ -1,6 +1,7 @@
package remote
import (
"context"
"encoding/json"
"errors"
"fmt"
@@ -9,8 +10,10 @@ import (
"net/http/httputil"
"net/url"
"platform/pkg/env"
"platform/pkg/rds"
"strconv"
"strings"
"time"
)
// CloudClient 定义云服务接口
@@ -28,16 +31,14 @@ type GatewayClient interface {
}
type cloud struct {
url string
token string
url string
}
var Cloud CloudClient
func Init() {
Cloud = &cloud{
url: env.RemoteAddr,
token: env.RemoteToken,
url: env.RemoteAddr,
}
}
@@ -260,34 +261,98 @@ func (c *cloud) requestCloud(method string, url string, data string) (*http.Resp
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("token", c.token)
if env.DebugHttpDump {
str, err := httputil.DumpRequest(req, true)
var resp *http.Response
for range 2 {
token, err := c.token(false)
if err != nil {
return nil, err
}
fmt.Println("==============================")
fmt.Println(string(str))
}
req.Header.Set("token", token)
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if env.DebugHttpDump {
str, err := httputil.DumpRequest(req, true)
if err != nil {
return nil, err
}
fmt.Println("==============================")
fmt.Println(string(str))
}
if env.DebugHttpDump {
str, err := httputil.DumpResponse(resp, true)
resp, err = http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
fmt.Println("==============================")
fmt.Println(string(str))
if env.DebugHttpDump {
str, err := httputil.DumpResponse(resp, true)
if err != nil {
return nil, err
}
fmt.Println("==============================")
fmt.Println(string(str))
}
if resp.StatusCode != 401 {
break
}
}
return resp, nil
}
func (c *cloud) token(refresh bool) (string, error) {
// redis 获取令牌
if !refresh {
token, err := rds.Client.Get(context.Background(), "remote:token").Result()
if err == nil && token != "" {
return token, nil
}
}
// redis 获取失败,重新获取
resp, err := http.Get(env.RemoteToken)
if err != nil {
return "", err
}
defer func(Body io.ReadCloser) {
_ = Body.Close()
}(resp.Body)
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
return "", err
}
fmt.Println(string(dump))
if resp.StatusCode != http.StatusOK {
return "", errors.New("failed to get token")
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return "", err
}
var result map[string]any
err = json.Unmarshal(body, &result)
if err != nil {
return "", err
}
if result["code"].(float64) != 1 {
return "", errors.New("failed to get cloud token")
}
// redis 设置令牌
token := result["token"].(string)
err = rds.Client.Set(context.Background(), "remote:token", token, 1*time.Hour).Err()
if err != nil {
return "", err
}
return token, nil
}
type gateway struct {
url string
username string

View File

@@ -2,39 +2,38 @@ package testutil
import (
"platform/pkg/orm"
"platform/web/models"
q "platform/web/queries"
"testing"
"github.com/DATA-DOG/go-sqlmock"
"gorm.io/driver/postgres"
"github.com/glebarez/sqlite"
"gorm.io/gorm"
)
// SetupDBTest 创建一个带有 sqlmock 的 GORM 数据库连接
func SetupDBTest(t *testing.T) sqlmock.Sqlmock {
// 创建 sqlmock
db, mock, err := sqlmock.New()
// SetupDBTest 创建一个基于 SQLite 内存数据库的 GORM 连接
func SetupDBTest(t *testing.T) *gorm.DB {
// 使用 SQLite 内存数据库
gormDB, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
if err != nil {
t.Fatalf("创建sqlmock失败: %v", err)
t.Fatalf("gorm 打开 SQLite 内存数据库失败: %v", err)
}
// 配置 gorm 连接
gormDB, err := gorm.Open(postgres.New(postgres.Config{
Conn: db,
PreferSimpleProtocol: true, // 禁用 prepared statement 缓存
}), &gorm.Config{})
// 自动迁移数据表结构
err = gormDB.AutoMigrate(
&models.User{},
&models.Whitelist{},
&models.Resource{},
&models.ResourcePss{},
&models.Proxy{},
&models.Channel{},
)
if err != nil {
t.Fatalf("gorm 打开数据库连接失败: %v", err)
t.Fatalf("自动迁移表结构失败: %v", err)
}
// 设置全局数据库连接
q.SetDefault(gormDB)
orm.DB = gormDB
// 使用 t.Cleanup 确保测试结束后关闭数据库连接
t.Cleanup(func() {
db.Close()
})
return mock
return gormDB
}