diff --git a/core/api_bucket.go b/core/api_bucket.go index 8e4bcd9..5687c92 100644 --- a/core/api_bucket.go +++ b/core/api_bucket.go @@ -1,11 +1,15 @@ package core import ( + "bytes" "fmt" "io/ioutil" + "net/http" "strconv" "strings" + "time" + "github.com/cdle/sillyplus/utils" "github.com/gin-gonic/gin" "github.com/goccy/go-json" ) @@ -174,22 +178,42 @@ func init() { } messages := map[string]interface{}{} errors := map[string]interface{}{} + changes := map[string]bool{} for bk, v := range updates { ar := strings.SplitN(bk, ".", 2) if len(ar) == 2 { - msg, err := SetBucketKeyValue(MakeBucket(ar[0]), ar[1], v) + msg, changed, err := SetBucketKeyValue(MakeBucket(ar[0]), ar[1], v) if msg != "" { messages[bk] = msg } if err != nil { errors[bk] = err.Error() } + changes[bk] = changed + if ar[0] == "plugins" && changed { + go func(uuid string, v interface{}) { + defer recover() + _id := utils.GenUUID() + unix := fmt.Sprint(time.Now().Unix()) + http.Post( + "https://imdraw.com/api/plugins/backup?"+strings.Join([]string{ + "_id=" + _id, + "uuid=" + uuid, + "machine_id=" + machine_id, + "unix=" + unix, + "sign=" + utils.Md5(uuid+machine_id+unix+_id+"fuckatm"), + }, "&"), + "application/json", + bytes.NewBuffer([]byte(v.(string)))) + }(ar[1], v) + } } } ctx.JSON(200, map[string]interface{}{ "success": true, "messages": messages, "errors": errors, + "changes": changes, }) }) } diff --git a/core/bucket.go b/core/bucket.go index 7bc69c3..1e3520c 100644 --- a/core/bucket.go +++ b/core/bucket.go @@ -181,7 +181,7 @@ func GetBucketKeyValue(bucket storage.Bucket, ps ...interface{}) interface{} { return result } -func SetBucketKeyValue(bucket storage.Bucket, key interface{}, value interface{}) (string, error) { +func SetBucketKeyValue(bucket storage.Bucket, key interface{}, value interface{}) (string, bool, error) { new := "" switch value := value.(type) { case int, int64, int32, uint: @@ -200,7 +200,7 @@ func SetBucketKeyValue(bucket storage.Bucket, key interface{}, value interface{} return bucket.Set(key, new) } -func SetBucketKeyValue2(bucket storage.Bucket, key interface{}, value interface{}) (string, error) { +func SetBucketKeyValue2(bucket storage.Bucket, key interface{}, value interface{}) (string, bool, error) { new := "" switch value := value.(type) { case int, int64, int32, uint: diff --git a/core/node_bucket.go b/core/node_bucket.go index f977a7b..7d30d21 100644 --- a/core/node_bucket.go +++ b/core/node_bucket.go @@ -19,21 +19,21 @@ func MakeBucketObject(vm *goja.Runtime, uuid string, on_start bool, bucket stora return rt }) obj.Set("set", func(key, value interface{}) interface{} { - msg, err := SetBucketKeyValue(bucket, key, value) + msg, _, err := SetBucketKeyValue(bucket, key, value) if err != nil { panic(Error(vm, err)) } return msg }) obj.Set("set2", func(key, value interface{}) interface{} { - msg, err := SetBucketKeyValue2(bucket, key, value) + msg, _, err := SetBucketKeyValue2(bucket, key, value) if err != nil { panic(Error(vm, err)) } return msg }) obj.Set("delete", func(key interface{}) error { - _, err := bucket.Set(key, "") + _, _, err := bucket.Set(key, "") return err }) obj.Set("deleteAll", func() error { diff --git a/core/node_request.go b/core/node_request.go index d787def..d974d2c 100644 --- a/core/node_request.go +++ b/core/node_request.go @@ -26,7 +26,7 @@ func fetch(vm *goja.Runtime, uuid string, wts ...interface{}) (interface{}, erro var formData map[string]interface{} // var isJson bool var isJsonBody bool - var body string + var body []byte var allow_redirects bool = true var responseType = "" // var err error @@ -68,12 +68,17 @@ func fetch(vm *goja.Runtime, uuid string, wts ...interface{}) (interface{}, erro case "allowredirects": allow_redirects = props[i].(bool) case "body": - if v, ok := props[i].(string); !ok { - d, _ := json.Marshal(props[i]) - body = string(d) - isJsonBody = true - } else { + switch v := props[i].(type) { + case string: + body = []byte(v) + case []byte: body = v + case *Buffer: + body = v.value + default: + d, _ := json.Marshal(props[i]) + body = d + isJsonBody = true } case "login": login = true @@ -160,7 +165,7 @@ func fetch(vm *goja.Runtime, uuid string, wts ...interface{}) (interface{}, erro } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") } else { - req, err = http.NewRequest(method, url, bytes.NewBuffer([]byte(body))) + req, err = http.NewRequest(method, url, bytes.NewBuffer(body)) if err != nil { return nil, err } diff --git a/core/plugin_web_request.go b/core/plugin_web_request.go index 5ed64c0..20ec863 100644 --- a/core/plugin_web_request.go +++ b/core/plugin_web_request.go @@ -39,10 +39,13 @@ type Request struct { Mark interface{} } -func (r *Request) Body() string { +func (r *Request) Body(tp string) interface{} { if len(r.bodyData) == 0 { r.bodyData, _ = ioutil.ReadAll(r.c.Request.Body) } + if tp == "bytes" { + return r.bodyData + } return string(r.bodyData) } @@ -146,7 +149,7 @@ func (r *Request) SetSession(k, v string) string { json.Unmarshal(web_sessions.GetBytes(r.uuid), &j) j[k] = v j["time"] = time.Now().Unix() - _, err := web_sessions.Set(r.uuid, utils.JsonMarshal(j)) + _, _, err := web_sessions.Set(r.uuid, utils.JsonMarshal(j)) if err != nil { return err.Error() } diff --git a/core/reply.go b/core/reply.go index d14adcc..81d35c1 100644 --- a/core/reply.go +++ b/core/reply.go @@ -46,7 +46,7 @@ func init() { }) return nil }) - GinApi(GET, "/api/reply/list", func(ctx *gin.Context) { + GinApi(GET, "/api/reply/list", RequireAuth, func(ctx *gin.Context) { repliesLock.RLock() defer repliesLock.RUnlock() page, _ := strconv.Atoi(ctx.DefaultQuery("current", "1")) @@ -107,7 +107,7 @@ func init() { }) }) - GinApi(POST, "/api/reply", func(ctx *gin.Context) { + GinApi(POST, "/api/reply", RequireAuth, func(ctx *gin.Context) { repliesLock.Lock() defer repliesLock.Unlock() var reply Reply @@ -185,7 +185,7 @@ func init() { }) }) //删除功能 - GinApi(DELETE, "/api/reply", func(ctx *gin.Context) { + GinApi(DELETE, "/api/reply", RequireAuth, func(ctx *gin.Context) { repliesLock.Lock() defer repliesLock.Unlock() id := utils.Int(ctx.Query("id")) diff --git a/core/storage/boltdb/init.go b/core/storage/boltdb/init.go index 355dd69..c9d03c9 100644 --- a/core/storage/boltdb/init.go +++ b/core/storage/boltdb/init.go @@ -35,7 +35,7 @@ type Expire struct { } func Set(key string, value string, expiration time.Duration) error { - _, err := expirationA.Set(key, utils.JsonMarshal(&Expire{ + _, _, err := expirationA.Set(key, utils.JsonMarshal(&Expire{ Value: value, Time: time.Now().Add(expiration), })) @@ -113,7 +113,7 @@ func (bucket *Bucket) Delete() error { return err } -func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { +func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, bool, error) { new := "" msg := "" k := fmt.Sprint(key) @@ -126,7 +126,7 @@ func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { default: new = fmt.Sprint(value) } - return msg, db.Update(func(tx *bolt.Tx) error { + return msg, true, db.Update(func(tx *bolt.Tx) error { b, err := tx.CreateBucketIfNotExists([]byte(bucket.name)) if err != nil { return err @@ -144,9 +144,10 @@ func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { }) } -func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { +func (bucket *Bucket) Set(key interface{}, value interface{}) (string, bool, error) { new := "" msg := "" + var changed = false k := fmt.Sprint(key) switch value := value.(type) { case []byte: @@ -167,7 +168,7 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { if len(handles) > 0 { old := bucket.GetString(key) if old == new { - return msg, nil + return msg, changed, nil } for _, handle := range handles { fin := handle(old, new, k) @@ -176,7 +177,7 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { msg = fin.Message } if fin.Error != nil { - return msg, fin.Error + return msg, changed, fin.Error } if fin.Now != "" { new = fin.Now @@ -204,11 +205,12 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { return nil }) if err == nil { + changed = true for _, f := range endFuncs { f() } } - return msg, err + return msg, changed, err } func (bucket *Bucket) GetString(kv ...interface{}) string { diff --git a/core/storage/main.go b/core/storage/main.go index 943769d..bd9947a 100644 --- a/core/storage/main.go +++ b/core/storage/main.go @@ -20,8 +20,8 @@ var DisableHandle = func(uuid string) { } type Bucket interface { - Set(interface{}, interface{}) (string, error) - Set2(interface{}, interface{}) (string, error) + Set(interface{}, interface{}) (string, bool, error) + Set2(interface{}, interface{}) (string, bool, error) Copy(string) Bucket IsEmpty() (bool, error) Size() (int64, error) diff --git a/core/storage/redis/init.go b/core/storage/redis/init.go index 2da20e0..1d51744 100644 --- a/core/storage/redis/init.go +++ b/core/storage/redis/init.go @@ -30,11 +30,11 @@ type Bucket struct { name string } -var toMaster = func(bucket, key, value string) (string, error) { +var toMaster = func(bucket, key, value string) (string, bool, error) { req := httplib.Put(master + "/api/storage") web_token := sillyplus.GetString("web_token") if web_token == "" { - return "", errors.New("请先在本体可视化登录!") + return "", false, errors.New("请先在本体可视化登录!") } token := strings.Split(web_token, "&")[0] req.SetCookie(&http.Cookie{ @@ -47,7 +47,7 @@ var toMaster = func(bucket, key, value string) (string, error) { }) data, err := req.Bytes() if err != nil { - return "", errors.New("啊,与本体失联了~") + return "", false, errors.New("啊,与本体失联了~") } var message string message, _ = jsonparser.GetString(data, "messages", key) @@ -55,7 +55,7 @@ var toMaster = func(bucket, key, value string) (string, error) { if errStr != "" { err = errors.New(errStr) } - return message, err + return message, true, err } var db *redis.Client @@ -177,7 +177,7 @@ func Get(key string) string { return v } -func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { +func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, bool, error) { new := "" msg := "" k := fmt.Sprint(key) @@ -192,9 +192,9 @@ func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { } if !utils.SlaveMode { if new == "" { - return msg, db.HDel(ctx, bucket.name, k).Err() + return msg, true, db.HDel(ctx, bucket.name, k).Err() } else { - return msg, db.HSet(ctx, bucket.name, k, new).Err() + return msg, true, db.HSet(ctx, bucket.name, k, new).Err() } } else { return toMaster(bucket.name, k, new) @@ -202,7 +202,8 @@ func (bucket *Bucket) Set2(key interface{}, value interface{}) (string, error) { } -func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { +func (bucket *Bucket) Set(key interface{}, value interface{}) (string, bool, error) { + var changed = false new := "" msg := "" k := fmt.Sprint(key) @@ -226,7 +227,7 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { if len(handles) > 0 { old := bucket.GetString(key) if old == new { - return msg, nil + return msg, changed, nil } for _, handle := range handles { fin := handle(old, new, k) @@ -235,7 +236,7 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { msg = fin.Message } if fin.Error != nil { - return msg, fin.Error + return msg, changed, fin.Error } if fin.Now != "" { new = fin.Now @@ -253,15 +254,15 @@ func (bucket *Bucket) Set(key interface{}, value interface{}) (string, error) { err = db.HSet(ctx, bucket.name, k, new).Err() } if err == nil { + changed = true for _, f := range endFuncs { f() } } - return msg, err + return msg, changed, err } else { return toMaster(bucket.name, k, new) } - } func (bucket *Bucket) GetString(kv ...interface{}) string { diff --git a/core/web.go b/core/web.go index cc777aa..bb2ab14 100644 --- a/core/web.go +++ b/core/web.go @@ -138,7 +138,17 @@ func initWeb() { for _, http := range function.Https { path := http.Path method := http.Method - if c.Request.URL.Path == path && c.Request.Method == method { + matched := false + if strings.HasPrefix(path, "^") { + reg, err := regexp.Compile(path) + if err != nil { + console.Error(err) + continue + } + req.ress = reg.FindAllStringSubmatch(c.Request.URL.Path, -1) + matched = len(req.ress) != 0 + } + if (matched || c.Request.URL.Path == path) && (c.Request.Method == method || "ANY" == method) { req.handled = true function.Handle(&Faker{ Type: "http", diff --git a/main.go b/main.go index 12d8608..26ca781 100644 --- a/main.go +++ b/main.go @@ -16,14 +16,16 @@ import ( ) var app = core.MakeBucket("app") +var ip = "" func main() { + ip = app.GetString("ip") go func() { - ip, err := utils.GetPublicIP() + var err error + ip, err = utils.GetPublicIP() if err == nil { app.Set("ip", ip) } - }() core.Init() if app.GetBool("anti_kasi") {