feat(handlers): add duplicate login check and improve request handling

refactor: move postLog package to root directory and enhance logging
fix(frpc): improve request parsing and type handling for instance creation
chore: update config paths and enable debug mode
This commit is contained in:
2026-02-27 21:04:08 +08:00
parent 7e163b5216
commit 962a36d74f
7 changed files with 112 additions and 27 deletions
+83 -9
View File
@@ -10,18 +10,19 @@ import (
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"time"
)
type InstanceInfo struct {
Name string `json:"name"`
ServerAddr string `json:"serverAddr"`
ServerPort string `json:"serverPort"`
AuthMethod string `json:"auth_method"`
Name string `json:"name"`
ServerAddr string `json:"serverAddr"`
ServerPort string `json:"serverPort"`
AuthMethod string `json:"auth_method"`
// BootAtStart bool `json:"bootAtStart"`
RunUser string `json:"runUser"`
Additional map[string]interface{} `json:"additionalProperties"`
RunUser string `json:"runUser"`
Additional map[string]interface{} `json:"additionalProperties"`
}
type CreateInstanceRequest struct {
@@ -102,13 +103,79 @@ func CreateInstanceHandler(w http.ResponseWriter, r *http.Request) {
}
defer r.Body.Close()
var req CreateInstanceRequest
if err := json.Unmarshal(body, &req); err != nil {
// 先解析为map,处理类型不匹配的情况
var reqMap map[string]interface{}
if err := json.Unmarshal(body, &reqMap); err != nil {
SendErrorResponse(w, http.StatusBadRequest, "invalid request format")
return
}
userID, _, err := ValidateRequestWithBody(w, r, body)
// 处理timeStamp字段
timeStamp := int64(0)
if ts, ok := reqMap["timeStamp"]; ok {
switch v := ts.(type) {
case float64:
timeStamp = int64(v)
case string:
if v != "" {
if parsed, err := strconv.ParseInt(v, 10, 64); err == nil {
timeStamp = parsed
}
}
}
}
// 处理bootAtStart字段
bootAtStart := false
if bas, ok := reqMap["bootAtStart"]; ok {
switch v := bas.(type) {
case bool:
bootAtStart = v
case string:
if v == "true" {
bootAtStart = true
}
}
}
// 处理instanceInfo字段
instanceInfoMap, ok := reqMap["instanceInfo"].(map[string]interface{})
if !ok {
SendErrorResponse(w, http.StatusBadRequest, "invalid instanceInfo format")
return
}
instanceInfo := InstanceInfo{
Name: getStringFromMap(instanceInfoMap, "name"),
ServerAddr: getStringFromMap(instanceInfoMap, "serverAddr"),
ServerPort: getStringFromMap(instanceInfoMap, "serverPort"),
AuthMethod: getStringFromMap(instanceInfoMap, "auth_method"),
RunUser: getStringFromMap(reqMap, "runUser"),
}
// 处理additionalProperties字段
if additional, ok := reqMap["additionalProperties"].(map[string]interface{}); ok {
instanceInfo.Additional = additional
}
// 构建请求结构体
req := CreateInstanceRequest{
Token: getStringFromMap(reqMap, "token"),
TimeStamp: timeStamp,
InstanceInfo: instanceInfo,
BootAtStart: bootAtStart,
RunUser: instanceInfo.RunUser,
Additional: instanceInfo.Additional,
}
// 重新序列化为JSON,用于ValidateRequestWithBody
reqBody, err := json.Marshal(req)
if err != nil {
SendErrorResponse(w, http.StatusBadRequest, "invalid request format")
return
}
userID, _, err := ValidateRequestWithBody(w, r, reqBody)
if err != nil {
SendErrorResponse(w, http.StatusUnauthorized, err.Error())
return
@@ -745,3 +812,10 @@ func GetUserInstances(userID int) ([]FrpcInstance, error) {
return instances, nil
}
func getStringFromMap(m map[string]interface{}, key string) string {
if v, ok := m[key].(string); ok {
return v
}
return ""
}