update keepKeyCase to default true

add requires for verify args
fix bug of load config from yml
fix bug of can't stop on kill
This commit is contained in:
Star 2024-10-26 23:37:41 +08:00
parent e1dc87d733
commit d416c61a6a
3 changed files with 43 additions and 9 deletions

6
go.mod
View File

@ -3,17 +3,17 @@ module apigo.cc/gojs/service
go 1.18 go 1.18
require ( require (
apigo.cc/gojs v0.0.3 apigo.cc/gojs v0.0.4
apigo.cc/gojs/console v0.0.1 apigo.cc/gojs/console v0.0.1
apigo.cc/gojs/http v0.0.3 apigo.cc/gojs/http v0.0.3
apigo.cc/gojs/util v0.0.2 apigo.cc/gojs/util v0.0.3
github.com/gorilla/websocket v1.5.3 github.com/gorilla/websocket v1.5.3
github.com/ssgo/config v1.7.8 github.com/ssgo/config v1.7.8
github.com/ssgo/discover v1.7.9 github.com/ssgo/discover v1.7.9
github.com/ssgo/httpclient v1.7.8 github.com/ssgo/httpclient v1.7.8
github.com/ssgo/log v1.7.7 github.com/ssgo/log v1.7.7
github.com/ssgo/redis v1.7.7 github.com/ssgo/redis v1.7.7
github.com/ssgo/s v1.7.17 github.com/ssgo/s v1.7.18
github.com/ssgo/standard v1.7.7 github.com/ssgo/standard v1.7.7
github.com/ssgo/u v1.7.9 github.com/ssgo/u v1.7.9
) )

View File

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"strings" "strings"
@ -66,10 +67,17 @@ var serviceConfig Config
var onStop goja.Callable var onStop goja.Callable
var limiters = map[string]*s.Limiter{} var limiters = map[string]*s.Limiter{}
var configed = false
func init() { func init() {
s.Config.KeepKeyCase = true
obj := map[string]any{ obj := map[string]any{
"config": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "config": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
configed = true
s.InitConfig()
if startPath, ok := vm.GoData["startPath"]; ok {
s.SetWorkPath(u.String(startPath))
}
// 处理配置 // 处理配置
args := gojs.MakeArgs(&argsIn, vm) args := gojs.MakeArgs(&argsIn, vm)
serviceConfig = Config{"Session", "Device", "Client", "userId", "", 3600, "auth failed", "verify failed", "too many requests", nil, "", map[string]string{}, map[string]string{}, map[string]string{}} serviceConfig = Config{"Session", "Device", "Client", "userId", "", 3600, "auth failed", "verify failed", "too many requests", nil, "", map[string]string{}, map[string]string{}, map[string]string{}}
@ -165,6 +173,9 @@ func init() {
return nil return nil
}, },
"start": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "start": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
if !configed {
panic(vm.NewGoError(errors.New("must run service.config frist")))
}
if server != nil { if server != nil {
panic(vm.NewGoError(errors.New("server already started"))) panic(vm.NewGoError(errors.New("server already started")))
} }
@ -190,6 +201,9 @@ func init() {
} }
}) })
server.OnStopped(func() { server.OnStopped(func() {
ClearRewritesAndProxies()
pools = map[string]*gojs.Pool{}
server = nil
if waitChan != nil { if waitChan != nil {
waitChan <- true waitChan <- true
} }
@ -201,9 +215,6 @@ func init() {
panic(vm.NewGoError(errors.New("server not started"))) panic(vm.NewGoError(errors.New("server not started")))
} }
server.Stop() server.Stop()
ClearRewritesAndProxies()
pools = map[string]*gojs.Pool{}
server = nil
return nil return nil
}, },
"register": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value { "register": func(argsIn goja.FunctionCall, vm *goja.Runtime) goja.Value {
@ -225,6 +236,13 @@ func init() {
usedLimiters = append(usedLimiters, limiter1) usedLimiters = append(usedLimiters, limiter1)
} }
} }
if requiresObj := o.Array("requires"); requiresObj != nil {
requires := make([]string, len(requiresObj))
for i, require := range requiresObj {
requires[i] = u.String(require)
}
vm.GoData[fmt.Sprint("REQUIRE_"+host, method, path)] = requires
}
if verifiesObj := o.Obj("verifies"); verifiesObj != nil { if verifiesObj := o.Obj("verifies"); verifiesObj != nil {
verifiesSet := map[string]func(any, *goja.Runtime) bool{} verifiesSet := map[string]func(any, *goja.Runtime) bool{}
for _, field := range verifiesObj.Keys() { for _, field := range verifiesObj.Keys() {
@ -319,7 +337,8 @@ func init() {
} }
} }
if !u.FileExists(actionFile) { if !u.FileExists(actionFile) {
panic(vm.NewGoError(errors.New("actionFile must be a js file path"))) fullActionFile, _ := filepath.Abs(actionFile)
panic(vm.NewGoError(errors.New("actionFile must be a js file path: " + fullActionFile)))
} }
actionCode := u.ReadFileN(actionFile) actionCode := u.ReadFileN(actionFile)
if !strings.Contains(actionCode, "function main(") || !strings.Contains(actionCode, ".register(") { if !strings.Contains(actionCode, "function main(") || !strings.Contains(actionCode, ".register(") {
@ -363,7 +382,6 @@ func init() {
if err != nil { if err != nil {
panic(vm.NewGoError(err)) panic(vm.NewGoError(err))
} }
println(u.BMagenta("taskFile: "), taskFile, interval)
s.NewTimerServer(taskFile, time.Duration(interval)*time.Millisecond, func(isRunning *bool) { s.NewTimerServer(taskFile, time.Duration(interval)*time.Millisecond, func(isRunning *bool) {
rt.RunCode("if(onRun)onRun()") rt.RunCode("if(onRun)onRun()")
}, func() { }, func() {
@ -390,6 +408,11 @@ func init() {
Object: obj, Object: obj,
TsCode: serviceTS, TsCode: serviceTS,
Example: serviceMD, Example: serviceMD,
OnKill: func() {
if server != nil {
server.Stop()
}
},
WaitForStop: func() { WaitForStop: func() {
if waitChan != nil { if waitChan != nil {
<-waitChan <-waitChan
@ -487,6 +510,15 @@ func runAction(action goja.Callable, vm *goja.Runtime, thisArg goja.Value, args
// 验证请求参数的有效性 // 验证请求参数的有效性
if verifies, ok := vm.GoData["VERIFY_"+u.String(request.Get("registerTag"))].(map[string]func(any, *goja.Runtime) bool); ok { if verifies, ok := vm.GoData["VERIFY_"+u.String(request.Get("registerTag"))].(map[string]func(any, *goja.Runtime) bool); ok {
failedFields := make([]string, 0) failedFields := make([]string, 0)
// 检查必填字段
if requires, ok := vm.GoData["REQUIRE_"+u.String(request.Get("registerTag"))].([]string); ok {
for _, requireField := range requires {
if _, ok := args[requireField]; !ok {
failedFields = append(failedFields, requireField)
}
}
}
// 验证数据有效性
for k, v := range args { for k, v := range args {
if verifier, ok1 := verifies[k]; ok1 { if verifier, ok1 := verifies[k]; ok1 {
if !verifier(v, vm) { if !verifier(v, vm) {

View File

@ -75,7 +75,7 @@ interface Config {
memoryLimitTimes: number // 内存超过最高占用值超过次数1-100将报警如果MemoryMonitor开启的话默认6即30秒内连续6次 memoryLimitTimes: number // 内存超过最高占用值超过次数1-100将报警如果MemoryMonitor开启的话默认6即30秒内连续6次
cookieScope: string // 启用Session时Cookie的有效范围host|domain|topDomain默认值为host cookieScope: string // 启用Session时Cookie的有效范围host|domain|topDomain默认值为host
idServer: string // 用s.UniqueId、s.Id来生成唯一ID雪花算法时所需的redis服务器连接如果不指定将不能实现跨服务的全局唯一 idServer: string // 用s.UniqueId、s.Id来生成唯一ID雪花算法时所需的redis服务器连接如果不指定将不能实现跨服务的全局唯一
keepKeyCase: boolean // 是否保持Key的首字母大小写默认一律使用小写 keepKeyCase: boolean // 是否保持Key的首字母大小写默认保持设置为false则自动将首字母转为小写
indexFiles: string[] // 访问静态文件时的索引文件,默认为 index.html indexFiles: string[] // 访问静态文件时的索引文件,默认为 index.html
indexDir: boolean // 访问目录时显示文件列表 indexDir: boolean // 访问目录时显示文件列表
readTimeout: number // 读取请求的超时时间单位ms readTimeout: number // 读取请求的超时时间单位ms
@ -145,6 +145,8 @@ interface RegisterOption {
noBody: boolean noBody: boolean
noLog200: boolean noLog200: boolean
limiters: string[] limiters: string[]
verifies: Object
requires: string[]
onMessage: (params: OnMessageParams) => void onMessage: (params: OnMessageParams) => void
onClose: (params: RequestParams) => void onClose: (params: RequestParams) => void
} }