mirror of
https://shylinux.com/x/icebergs
synced 2025-04-26 01:24:05 +08:00
opt web
This commit is contained in:
parent
6d7e26b887
commit
ec83a5b39c
@ -71,11 +71,11 @@ func SessCheck(m *ice.Message, sessid string) bool {
|
||||
m.Options(ice.MSG_USERNAME, "", ice.MSG_USERNICK, "", ice.MSG_USERROLE, VOID)
|
||||
return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != ""
|
||||
}
|
||||
func SessAuth(m *ice.Message, value ice.Map, arg ...string) {
|
||||
func SessAuth(m *ice.Message, value ice.Any, arg ...string) {
|
||||
m.Auth(
|
||||
USERNAME, m.Option(ice.MSG_USERNAME, value[USERNAME]),
|
||||
USERNICK, m.Option(ice.MSG_USERNICK, value[USERNICK]),
|
||||
USERROLE, m.Option(ice.MSG_USERROLE, value[USERROLE]),
|
||||
USERNAME, m.Option(ice.MSG_USERNAME, kit.Value(value, USERNAME)),
|
||||
USERNICK, m.Option(ice.MSG_USERNICK, kit.Value(value, USERNICK)),
|
||||
USERROLE, m.Option(ice.MSG_USERROLE, kit.Value(value, USERROLE)),
|
||||
arg, logs.FileLineMeta(kit.Select(logs.FileLine(-1), m.Option("log.caller"))),
|
||||
)
|
||||
}
|
||||
|
@ -53,3 +53,7 @@ func init() {
|
||||
}, mdb.HashAction(mdb.SHORT, FROM, mdb.FIELD, "time,hash,from,file", mdb.ACTION, mdb.REVERT))},
|
||||
})
|
||||
}
|
||||
|
||||
func Trash(m *ice.Message, p string) *ice.Message {
|
||||
return m.Cmd(TRASH, mdb.CREATE, p)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func _port_right(m *ice.Message, arg ...string) string {
|
||||
}
|
||||
for i := current; i < end; i++ {
|
||||
if p := path.Join(ice.USR_LOCAL_DAEMON, kit.Format(i)); nfs.ExistsFile(m, p) {
|
||||
|
||||
|
||||
} else if c, e := net.Dial(TCP, kit.Format(":%d", i)); e == nil {
|
||||
m.Info("port exists %v", i)
|
||||
c.Close()
|
||||
@ -43,11 +43,11 @@ const PORT = "port"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
PORT: {Name: "port port path auto", Help: "端口", Actions: ice.MergeActions(ice.Actions{
|
||||
CURRENT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.Config(CURRENT)) }},
|
||||
CURRENT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.Config(CURRENT)) }},
|
||||
aaa.RIGHT: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_port_right(m, arg...)) }},
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Assert(m.Option(PORT) != "")
|
||||
m.Cmd(nfs.TRASH, path.Join(ice.USR_LOCAL_DAEMON, m.Option(PORT)))
|
||||
nfs.Trash(m, path.Join(ice.USR_LOCAL_DAEMON, m.Option(PORT)))
|
||||
}},
|
||||
}, mdb.HashAction(BEGIN, 10000, CURRENT, 10000, END, 20000)), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 {
|
||||
|
@ -1,428 +0,0 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _story_list(m *ice.Message, name string, key string) {
|
||||
if name == "" {
|
||||
m.Richs(STORY, HEAD, mdb.FOREACH, func(key string, value ice.Map) {
|
||||
m.Push(key, value, []string{mdb.TIME, mdb.COUNT, STORY})
|
||||
})
|
||||
m.SortTimeR(mdb.TIME)
|
||||
return
|
||||
}
|
||||
if key == "" {
|
||||
_story_history(m, name)
|
||||
return
|
||||
}
|
||||
|
||||
m.Richs(STORY, nil, key, func(key string, value ice.Map) {
|
||||
m.Push(mdb.DETAIL, value)
|
||||
})
|
||||
|
||||
}
|
||||
func _story_index(m *ice.Message, name string, withdata bool) {
|
||||
m.Richs(STORY, HEAD, name, func(key string, value ice.Map) {
|
||||
// 查询索引
|
||||
m.Push(HEAD, key)
|
||||
name = kit.Format(value[LIST])
|
||||
})
|
||||
|
||||
m.Richs(STORY, nil, name, func(key string, value ice.Map) {
|
||||
// 查询节点
|
||||
m.Push(LIST, key)
|
||||
m.Push(key, value, []string{SCENE, STORY})
|
||||
name = kit.Format(value[DATA])
|
||||
})
|
||||
|
||||
m.Richs(CACHE, nil, name, func(key string, value ice.Map) {
|
||||
// 查询数据
|
||||
m.Push(DATA, key)
|
||||
m.Push(key, value, []string{mdb.TEXT, nfs.FILE, nfs.SIZE, mdb.TIME, mdb.NAME, mdb.TYPE})
|
||||
if withdata {
|
||||
if value[nfs.FILE] == "" {
|
||||
m.Echo("%s", kit.Format(value[mdb.TEXT]))
|
||||
} else {
|
||||
m.Echo("%s", m.Cmdx(nfs.CAT, value[nfs.FILE]))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
func _story_history(m *ice.Message, name string) {
|
||||
// 历史记录
|
||||
list := m.Cmd(STORY, INDEX, name).Append(LIST)
|
||||
for i := 0; i < kit.Int(kit.Select("30", m.Option(ice.CACHE_LIMIT))) && list != ""; i++ {
|
||||
m.Richs(STORY, nil, list, func(key string, value ice.Map) {
|
||||
// 直连节点
|
||||
m.Push(key, value, []string{mdb.TIME, mdb.KEY, mdb.COUNT, SCENE, STORY})
|
||||
m.Richs(CACHE, nil, value[DATA], func(key string, value ice.Map) {
|
||||
m.Push(DRAMA, value[mdb.TEXT])
|
||||
m.Push(DATA, key)
|
||||
})
|
||||
|
||||
kit.Fetch(value[LIST], func(key string, val string) {
|
||||
m.Richs(STORY, nil, val, func(key string, value ice.Map) {
|
||||
// 复合节点
|
||||
m.Push(key, value, []string{mdb.TIME, mdb.KEY, mdb.COUNT, SCENE, STORY})
|
||||
m.Richs(CACHE, nil, value[DATA], func(key string, value ice.Map) {
|
||||
m.Push(DRAMA, value[mdb.TEXT])
|
||||
m.Push(DATA, key)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// 切换节点
|
||||
list = kit.Format(value[PREV])
|
||||
})
|
||||
}
|
||||
}
|
||||
func _story_write(m *ice.Message, scene, name, text string, arg ...string) {
|
||||
if len(arg) < 1 || text == "" || m.Richs(CACHE, nil, text, func(key string, value ice.Map) { text = key }) == nil {
|
||||
// 添加缓存
|
||||
m.Cmdy(CACHE, CATCH, scene, name, text, arg)
|
||||
scene, name, text = m.Append(mdb.TYPE), m.Append(mdb.NAME), m.Append(DATA)
|
||||
}
|
||||
|
||||
// 查询索引
|
||||
head, prev, value, count := "", "", kit.Dict(), 0
|
||||
m.Richs(STORY, HEAD, name, func(key string, val ice.Map) {
|
||||
head, prev, value, count = key, kit.Format(val[LIST]), val, kit.Int(val[mdb.COUNT])
|
||||
m.Logs("info", HEAD, head, PREV, prev, mdb.COUNT, count)
|
||||
})
|
||||
|
||||
if last := m.Richs(STORY, nil, prev, nil); prev != "" && last != nil && last[DATA] == text {
|
||||
// 重复提交
|
||||
m.Push(prev, last, []string{mdb.TIME, mdb.COUNT, mdb.KEY})
|
||||
m.Logs("info", "file", "exists")
|
||||
m.Echo(prev)
|
||||
return
|
||||
}
|
||||
|
||||
// 添加节点
|
||||
list := m.Rich(STORY, nil, kit.Dict(
|
||||
SCENE, scene, STORY, name, mdb.COUNT, count+1, DATA, text, PREV, prev,
|
||||
))
|
||||
m.Log_CREATE(STORY, list, mdb.TYPE, scene, mdb.NAME, name)
|
||||
m.Push(mdb.COUNT, count+1)
|
||||
m.Push(mdb.KEY, list)
|
||||
|
||||
if head == "" {
|
||||
// 添加索引
|
||||
m.Rich(STORY, HEAD, kit.Dict(SCENE, scene, STORY, name, mdb.COUNT, count+1, LIST, list))
|
||||
} else {
|
||||
// 更新索引
|
||||
value[mdb.COUNT] = count + 1
|
||||
value[mdb.TIME] = m.Time()
|
||||
value[LIST] = list
|
||||
}
|
||||
m.Echo(list)
|
||||
}
|
||||
func _story_catch(m *ice.Message, scene, name string, arg ...string) {
|
||||
if last := m.Richs(STORY, HEAD, name, nil); last != nil {
|
||||
if t, e := time.ParseInLocation(ice.MOD_TIME, kit.Format(last[mdb.TIME]), time.Local); e == nil {
|
||||
if s, e := nfs.StatFile(m, name); e == nil && s.ModTime().Before(t) {
|
||||
m.Push(name, last, []string{mdb.TIME, mdb.COUNT, mdb.KEY})
|
||||
m.Logs("info", "file", "exists")
|
||||
m.Echo("%s", last[LIST])
|
||||
// 重复提交
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
_story_write(m, scene, name, "", arg...)
|
||||
}
|
||||
func _story_watch(m *ice.Message, key, file string) {
|
||||
_story_index(m, key, false)
|
||||
_cache_watch(m, m.Append(DATA), file)
|
||||
}
|
||||
|
||||
const (
|
||||
HEAD = "head"
|
||||
LIST = "list"
|
||||
PREV = "prev"
|
||||
DATA = "data"
|
||||
|
||||
HISTORY = "history"
|
||||
|
||||
PULL = "pull"
|
||||
PUSH = "push"
|
||||
COMMIT = "commit"
|
||||
)
|
||||
const (
|
||||
SCENE = "scene"
|
||||
DRAMA = "drama"
|
||||
)
|
||||
const STORY = "story"
|
||||
|
||||
func init() {
|
||||
Index.Merge(&ice.Context{Configs: ice.Configs{
|
||||
STORY: {Name: "story", Help: "故事会", Value: kit.Dict(
|
||||
mdb.META, kit.Dict(mdb.SHORT, DATA),
|
||||
HEAD, kit.Data(mdb.SHORT, STORY),
|
||||
)},
|
||||
}, Commands: ice.Commands{
|
||||
STORY: {Name: "story story auto", Help: "故事会", Actions: ice.Actions{
|
||||
WRITE: {Name: "write type name text arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_write(m, arg[0], arg[1], arg[2], arg[3:]...)
|
||||
}},
|
||||
CATCH: {Name: "catch type name arg...", Help: "捕捉", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_catch(m, arg[0], arg[1], arg[2:]...)
|
||||
}},
|
||||
WATCH: {Name: "watch key name", Help: "释放", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_watch(m, arg[0], arg[1])
|
||||
}},
|
||||
INDEX: {Name: "index key", Help: "索引", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_index(m, arg[0], false)
|
||||
}},
|
||||
HISTORY: {Name: "history name", Help: "历史", Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_history(m, arg[0])
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
_story_list(m, kit.Select("", arg, 0), kit.Select("", arg, 1))
|
||||
}},
|
||||
"/story/": {Name: "/story/", Help: "故事会", Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case PULL:
|
||||
list := m.Cmd(STORY, INDEX, m.Option("begin")).Append("list")
|
||||
for i := 0; i < 10 && list != "" && list != m.Option("end"); i++ {
|
||||
if m.Richs(STORY, nil, list, func(key string, value ice.Map) {
|
||||
// 节点信息
|
||||
m.Push("list", key)
|
||||
m.Push("node", kit.Format(value))
|
||||
m.Push("data", value["data"])
|
||||
m.Push("save", kit.Format(m.Richs(CACHE, nil, value["data"], nil)))
|
||||
list = kit.Format(value["prev"])
|
||||
}) == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
m.Log(ice.LOG_EXPORT, "%s %s", m.Option("begin"), m.FormatSize())
|
||||
|
||||
case PUSH:
|
||||
if m.Richs(CACHE, nil, m.Option("data"), nil) == nil {
|
||||
// 导入缓存
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("data"), m.Option("save"))
|
||||
m.Conf(CACHE, kit.Keys("hash", m.Option("data")), kit.UnMarshal(m.Option("save")))
|
||||
}
|
||||
|
||||
node := kit.UnMarshal(m.Option("node")).(ice.Map)
|
||||
if m.Richs(STORY, nil, m.Option("list"), nil) == nil {
|
||||
// 导入节点
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", m.Option("list"), m.Option("node"))
|
||||
m.Conf(STORY, kit.Keys("hash", m.Option("list")), node)
|
||||
}
|
||||
|
||||
if head := m.Richs(STORY, "head", m.Option("story"), nil); head == nil {
|
||||
// 自动创建
|
||||
h := m.Rich(STORY, "head", kit.Dict(
|
||||
"scene", node["scene"], "story", m.Option("story"),
|
||||
"count", node["count"], "list", m.Option("list"),
|
||||
))
|
||||
m.Log(ice.LOG_CREATE, "%v: %v", h, m.Option("story"))
|
||||
} else if head["list"] == kit.Format(node["prev"]) || head["list"] == kit.Format(node["pull"]) {
|
||||
// 快速合并
|
||||
head["list"] = m.Option("list")
|
||||
head["count"] = node["count"]
|
||||
head["time"] = node["time"]
|
||||
} else {
|
||||
// 推送失败
|
||||
}
|
||||
|
||||
case UPLOAD:
|
||||
// 上传数据
|
||||
m.Cmdy(CACHE, "upload")
|
||||
|
||||
case DOWNLOAD:
|
||||
// 下载数据
|
||||
m.Cmdy(STORY, INDEX, arg[1])
|
||||
m.Render(kit.Select(ice.RENDER_DOWNLOAD, ice.RENDER_RESULT, m.Append("file") == ""), m.Append("text"))
|
||||
}
|
||||
}},
|
||||
}})
|
||||
}
|
||||
|
||||
func _story_pull(m *ice.Message, arg ...string) {
|
||||
// 起止节点
|
||||
prev, begin, end := "", arg[3], ""
|
||||
repos := kit.Keys("remote", arg[2], arg[3])
|
||||
m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) {
|
||||
end = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
|
||||
prev = kit.Format(val["list"])
|
||||
})
|
||||
|
||||
pull := end
|
||||
var first ice.Map
|
||||
for begin != "" && begin != end {
|
||||
if m.Cmd(SPIDE, arg[2], "msg", "/story/pull", "begin", begin, "end", end).Table(func(index int, value ice.Maps, head []string) {
|
||||
if m.Richs(CACHE, nil, value["data"], nil) == nil {
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", value["data"], value["save"])
|
||||
if node := kit.UnMarshal(value["save"]); kit.Format(kit.Value(node, "file")) != "" {
|
||||
// 下载文件
|
||||
m.Cmd(SPIDE, arg[2], "cache", "GET", "/story/download/"+value["data"])
|
||||
} else {
|
||||
// 导入缓存
|
||||
m.Conf(CACHE, kit.Keys("hash", value["data"]), node)
|
||||
}
|
||||
}
|
||||
|
||||
node := kit.UnMarshal(value["node"]).(ice.Map)
|
||||
if m.Richs(STORY, nil, value["list"], nil) == nil {
|
||||
// 导入节点
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", value["list"], value["node"])
|
||||
m.Conf(STORY, kit.Keys("hash", value["list"]), node)
|
||||
}
|
||||
|
||||
if first == nil {
|
||||
if m.Richs(STORY, "head", arg[1], nil) == nil {
|
||||
// 自动创建
|
||||
h := m.Rich(STORY, "head", kit.Dict(
|
||||
"scene", node["scene"], "story", arg[1],
|
||||
"count", node["count"], "list", value["list"],
|
||||
))
|
||||
m.Log(ice.LOG_CREATE, "%v: %v", h, node["story"])
|
||||
}
|
||||
|
||||
pull, first = kit.Format(value["list"]), node
|
||||
m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) {
|
||||
prev = kit.Format(val["list"])
|
||||
if kit.Int(node["count"]) > kit.Int(kit.Value(val, kit.Keys(repos, "pull", "count"))) {
|
||||
// 更新分支
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", arg[2], pull)
|
||||
kit.Value(val, kit.Keys(repos, "pull"), kit.Dict(
|
||||
"head", arg[3], "time", node["time"], "list", pull, "count", node["count"],
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if prev == kit.Format(node["prev"]) || prev == kit.Format(node["push"]) {
|
||||
// 快速合并
|
||||
m.Log(ice.LOG_IMPORT, "%v: %v", pull, arg[2])
|
||||
m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) {
|
||||
val["count"] = first["count"]
|
||||
val["time"] = first["time"]
|
||||
val["list"] = pull
|
||||
})
|
||||
prev = pull
|
||||
}
|
||||
|
||||
begin = kit.Format(node["prev"])
|
||||
}).Appendv("list") == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
func _story_push(m *ice.Message, arg ...string) {
|
||||
// 更新分支
|
||||
m.Cmdx(STORY, "pull", arg[1:])
|
||||
|
||||
repos := kit.Keys("remote", arg[2], arg[3])
|
||||
// 查询索引
|
||||
prev, pull, some, list := "", "", "", ""
|
||||
m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) {
|
||||
prev = kit.Format(val["list"])
|
||||
pull = kit.Format(kit.Value(val, kit.Keys(repos, "pull", "list")))
|
||||
for some = pull; prev != some && some != ""; {
|
||||
local := m.Richs(STORY, nil, prev, nil)
|
||||
remote := m.Richs(STORY, nil, some, nil)
|
||||
if diff := kit.Time(kit.Format(remote["time"])) - kit.Time(kit.Format(local["time"])); diff > 0 {
|
||||
some = kit.Format(remote["prev"])
|
||||
} else if diff < 0 {
|
||||
prev = kit.Format(local["prev"])
|
||||
}
|
||||
}
|
||||
|
||||
if prev = kit.Format(val["list"]); prev == pull {
|
||||
// 相同节点
|
||||
return
|
||||
}
|
||||
|
||||
if some != pull {
|
||||
// 合并节点
|
||||
local := m.Richs(STORY, nil, prev, nil)
|
||||
remote := m.Richs(STORY, nil, pull, nil)
|
||||
list = m.Rich(STORY, nil, kit.Dict(
|
||||
"scene", val["scene"], "story", val["story"], "count", kit.Int(remote["count"])+1,
|
||||
"data", local["data"], "prev", pull, "push", prev,
|
||||
))
|
||||
m.Log(ice.LOG_CREATE, "merge: %s %s->%s", list, prev, pull)
|
||||
val["list"] = list
|
||||
prev = list
|
||||
val["count"] = kit.Int(remote["count"]) + 1
|
||||
}
|
||||
|
||||
// 查询节点
|
||||
nodes := []string{}
|
||||
for list = prev; list != some; {
|
||||
m.Richs(STORY, nil, list, func(key string, value ice.Map) {
|
||||
nodes, list = append(nodes, list), kit.Format(value["prev"])
|
||||
})
|
||||
}
|
||||
|
||||
for _, v := range kit.Revert(nodes) {
|
||||
m.Richs(STORY, nil, v, func(list string, node ice.Map) {
|
||||
m.Richs(CACHE, nil, node["data"], func(data string, save ice.Map) {
|
||||
if kit.Format(save["file"]) != "" {
|
||||
// 推送缓存
|
||||
m.Cmd(SPIDE, arg[2], "/story/upload",
|
||||
"part", "upload", "@"+kit.Format(save["file"]),
|
||||
)
|
||||
}
|
||||
|
||||
// 推送节点
|
||||
m.Log(ice.LOG_EXPORT, "%s: %s", v, kit.Format(node))
|
||||
m.Cmd(SPIDE, arg[2], "/story/push",
|
||||
"story", arg[3], "list", v, "node", kit.Format(node),
|
||||
"data", node["data"], "save", kit.Format(save),
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 更新分支
|
||||
m.Cmd(STORY, "pull", arg[1:])
|
||||
|
||||
}
|
||||
func _story_commit(m *ice.Message, arg ...string) {
|
||||
// 查询索引
|
||||
head, prev, value, count := "", "", ice.Map{}, 0
|
||||
m.Richs(STORY, "head", arg[1], func(key string, val ice.Map) {
|
||||
head, prev, value, count = key, kit.Format(val["list"]), val, kit.Int(val["count"])
|
||||
m.Log("info", "head: %v prev: %v count: %v", head, prev, count)
|
||||
})
|
||||
|
||||
// 提交信息
|
||||
arg[2] = m.Cmdx(STORY, "add", "submit", arg[2], "hostname,username")
|
||||
|
||||
// 节点信息
|
||||
menu := ice.Maps{}
|
||||
for i := 3; i < len(arg); i++ {
|
||||
menu[arg[i]] = m.Cmdx(STORY, INDEX, arg[i])
|
||||
}
|
||||
|
||||
// 添加节点
|
||||
list := m.Rich(STORY, nil, kit.Dict(
|
||||
"scene", "commit", "story", arg[1], "count", count+1, "data", arg[2], "list", menu, "prev", prev,
|
||||
))
|
||||
m.Log(ice.LOG_CREATE, "commit: %s %s: %s", list, arg[1], arg[2])
|
||||
m.Push("list", list)
|
||||
|
||||
if head == "" {
|
||||
// 添加索引
|
||||
m.Rich(STORY, "head", kit.Dict("scene", "commit", "story", arg[1], "count", count+1, "list", list))
|
||||
} else {
|
||||
// 更新索引
|
||||
value["count"] = count + 1
|
||||
value["time"] = m.Time()
|
||||
value["list"] = list
|
||||
}
|
||||
m.Echo(list)
|
||||
}
|
@ -41,7 +41,6 @@ func _dream_show(m *ice.Message, name string) {
|
||||
name = m.Time("20060102-") + name
|
||||
}
|
||||
defer m.ProcessOpen(MergePod(m, m.Option(mdb.NAME, name)))
|
||||
|
||||
p := path.Join(ice.USR_LOCAL_WORK, name)
|
||||
if pid := m.Cmdx(nfs.CAT, path.Join(p, ice.Info.PidPath)); pid != "" && nfs.ExistsFile(m, "/proc/"+pid) {
|
||||
m.Info("already exists %v", pid)
|
||||
@ -50,10 +49,8 @@ func _dream_show(m *ice.Message, name string) {
|
||||
m.Info("already exists %v", name)
|
||||
return
|
||||
}
|
||||
|
||||
nfs.MkdirAll(m, p)
|
||||
_dream_template(m, p)
|
||||
|
||||
m.Optionv(cli.CMD_DIR, kit.Path(p))
|
||||
m.Optionv(cli.CMD_ENV, kit.Simple(
|
||||
cli.CTX_OPS, "http://:"+m.CmdAppend(SERVE, tcp.PORT),
|
||||
@ -63,7 +60,6 @@ func _dream_show(m *ice.Message, name string) {
|
||||
m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG))
|
||||
defer m.Options(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "")
|
||||
gdb.Event(m, DREAM_CREATE, m.OptionSimple(mdb.NAME, mdb.TYPE))
|
||||
|
||||
defer ToastProcess(m)()
|
||||
bin := kit.Select(os.Args[0], cli.SystemFind(m, ice.ICE_BIN, nfs.PWD+path.Join(p, ice.BIN), nfs.PWD+ice.BIN))
|
||||
m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, m.OptionSimple(mdb.NAME, RIVER), cli.DAEMON, ice.OPS)
|
||||
@ -117,20 +113,20 @@ func init() {
|
||||
cli.START: {Hand: func(m *ice.Message, arg ...string) {
|
||||
_dream_show(m, m.Option(mdb.NAME))
|
||||
}},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ProcessIframe(m, MergePod(m, m.Option(mdb.NAME)), arg...) }},
|
||||
cli.STOP: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
|
||||
m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) })
|
||||
ctx.ProcessRefresh(m, "1s")
|
||||
}},
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.TRASH, mdb.CREATE, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
|
||||
nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))
|
||||
}},
|
||||
DREAM_STOP: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if m.CmdAppend(SPACE, m.Option(mdb.NAME), mdb.STATUS) != cli.STOP {
|
||||
m.Go(func() { m.Sleep3s(DREAM, cli.START, m.OptionSimple(mdb.NAME)) })
|
||||
}
|
||||
}},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ProcessIframe(m, MergePod(m, m.Option(mdb.NAME)), arg...) }},
|
||||
}, ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
_dream_list(m)
|
||||
|
@ -2,7 +2,6 @@ package web
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
@ -13,7 +12,6 @@ import (
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/gdb"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/ssh"
|
||||
@ -22,40 +20,48 @@ import (
|
||||
"shylinux.com/x/toolkits/logs"
|
||||
)
|
||||
|
||||
var rewriteList = []ice.Any{}
|
||||
|
||||
func AddRewrite(cb ice.Any) { rewriteList = append(rewriteList, cb) }
|
||||
|
||||
func _serve_rewrite(m *ice.Message) {
|
||||
AddRewrite(func(w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Method != SPIDE_GET {
|
||||
return false
|
||||
func _serve_start(m *ice.Message) {
|
||||
if cli.NodeInfo(m, kit.Select(ice.Info.HostName, m.Option("nodename")), SERVER); m.Option(tcp.PORT) == tcp.RANDOM {
|
||||
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
|
||||
}
|
||||
aaa.UserRoot(m, m.Option(aaa.USERNAME), m.Option(aaa.USERNICK))
|
||||
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
|
||||
m.Sleep300ms().Go(func() { m.Cmd(BROAD, SERVE) })
|
||||
for _, k := range kit.Split(m.Option(ice.DEV)) {
|
||||
m.Cmd(SPACE, tcp.DIAL, ice.DEV, k, mdb.NAME, ice.Info.NodeName)
|
||||
}
|
||||
}
|
||||
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Header.Get("Index-Module") == "" {
|
||||
r.Header.Set("Index-Module", m.Prefix())
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
if ip := r.Header.Get("X-Real-Ip"); ip != "" {
|
||||
if r.Header.Set(ice.MSG_USERIP, ip); r.Header.Get("X-Real-Port") != "" {
|
||||
r.Header.Set(ice.MSG_USERADDR, ip+":"+r.Header.Get("X-Real-Port"))
|
||||
}
|
||||
|
||||
msg, repos := m.Spawn(SERVE, w, r), kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), "Mozilla/5.0"))
|
||||
switch r.URL.Path {
|
||||
case ice.PS:
|
||||
if repos == ice.VOLCANOS {
|
||||
return Render(msg, ice.RENDER_RESULT, RenderMain(msg, "", "").Result())
|
||||
}
|
||||
return Render(msg, ice.RENDER_DOWNLOAD, path.Join(msg.Config(kit.Keys(repos, nfs.PATH)), msg.Config(kit.Keys(repos, INDEX))))
|
||||
|
||||
case PP(ice.HELP):
|
||||
r.URL.Path = P(ice.HELP, "tutor.shy")
|
||||
}
|
||||
|
||||
p := path.Join(ice.USR, repos, r.URL.Path)
|
||||
if _, e := nfs.DiskFile.StatFile(p); e == nil {
|
||||
http.ServeFile(w, r, kit.Path(p))
|
||||
return true
|
||||
} else if f, e := nfs.PackFile.OpenFile(p); e == nil {
|
||||
defer f.Close()
|
||||
RenderType(w, p, "")
|
||||
io.Copy(w, f)
|
||||
return true
|
||||
} else if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, kit.Split(ip)[0])
|
||||
} else if strings.HasPrefix(r.RemoteAddr, "[") {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:])
|
||||
} else {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, ":")[0])
|
||||
}
|
||||
meta := logs.FileLineMeta("")
|
||||
m.Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL, meta)
|
||||
if m.Config(LOGHEADERS) == ice.TRUE {
|
||||
for k, v := range r.Header {
|
||||
m.Info("%s: %v", k, kit.Format(v), meta)
|
||||
}
|
||||
m.Info("", meta)
|
||||
}
|
||||
repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), "Mozilla/5.0"))
|
||||
if msg := gdb.Event(m.Spawn(w, r), SERVE_REWRITE, r.Method, r.URL.Path, path.Join(m.Conf(SERVE, kit.Keym(repos, nfs.PATH)), r.URL.Path), repos); msg.Option(ice.MSG_OUTPUT) != "" {
|
||||
Render(msg, msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
|
||||
return false
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
func _serve_domain(m *ice.Message) string {
|
||||
if p := ice.Info.Domain; p != "" {
|
||||
@ -75,244 +81,97 @@ func _serve_domain(m *ice.Message) string {
|
||||
return kit.Format("https://%s", m.R.Host)
|
||||
}
|
||||
}
|
||||
func _serve_spide(m *ice.Message, prefix string, c *ice.Context) {
|
||||
for k := range c.Commands {
|
||||
if strings.HasPrefix(k, ice.PS) {
|
||||
m.Push(nfs.PATH, path.Join(prefix, k)+kit.Select("", ice.PS, strings.HasSuffix(k, ice.PS)))
|
||||
}
|
||||
}
|
||||
for k, v := range c.Contexts {
|
||||
_serve_spide(m, path.Join(prefix, k), v)
|
||||
}
|
||||
}
|
||||
func _serve_start(m *ice.Message) {
|
||||
if cli.NodeInfo(m, kit.Select(ice.Info.HostName, m.Option("nodename")), SERVER); m.Option(tcp.PORT) == tcp.RANDOM {
|
||||
m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT))
|
||||
}
|
||||
aaa.UserRoot(m, m.Option(aaa.USERNAME), m.Option(aaa.USERNICK))
|
||||
|
||||
m.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
|
||||
m.Go(func() { m.Cmd(BROAD, SERVE) })
|
||||
m.Sleep300ms()
|
||||
|
||||
for _, k := range kit.Split(m.Option(ice.DEV)) {
|
||||
m.Cmd(SPACE, tcp.DIAL, ice.DEV, k, mdb.NAME, ice.Info.NodeName)
|
||||
}
|
||||
}
|
||||
|
||||
func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Header.Get("Index-Module") == "" {
|
||||
r.Header.Set("Index-Module", m.Prefix())
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
|
||||
// 用户地址
|
||||
if ip := r.Header.Get("X-Real-Ip"); ip != "" {
|
||||
if r.Header.Set(ice.MSG_USERIP, ip); r.Header.Get("X-Real-Port") != "" {
|
||||
r.Header.Set(ice.MSG_USERADDR, ip+":"+r.Header.Get("X-Real-Port"))
|
||||
}
|
||||
} else if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
|
||||
r.Header.Set(ice.MSG_USERIP, kit.Split(ip)[0])
|
||||
} else if strings.HasPrefix(r.RemoteAddr, "[") {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:])
|
||||
} else {
|
||||
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, ":")[0])
|
||||
}
|
||||
func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.ResponseWriter, r *http.Request) {
|
||||
meta := logs.FileLineMeta("")
|
||||
m.Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL, meta)
|
||||
|
||||
// 参数日志
|
||||
if m.Config(LOGHEADERS) == ice.TRUE {
|
||||
for k, v := range r.Header {
|
||||
m.Info("%s: %v", k, kit.Format(v), meta)
|
||||
}
|
||||
m.Info("", meta)
|
||||
|
||||
defer func() {
|
||||
m.Info("", meta)
|
||||
for k, v := range w.Header() {
|
||||
m.Info("%s: %v", k, kit.Format(v), meta)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 模块回调
|
||||
for _, h := range rewriteList {
|
||||
if m.Config(LOGHEADERS) == ice.TRUE {
|
||||
m.Info("%s: %v", r.URL.Path, logs.FileLine(h), meta)
|
||||
}
|
||||
switch h := h.(type) {
|
||||
case func(w http.ResponseWriter, r *http.Request) func():
|
||||
defer h(w, r)
|
||||
|
||||
case func(p string, w http.ResponseWriter, r *http.Request) bool:
|
||||
if h(r.URL.Path, w, r) {
|
||||
return false
|
||||
}
|
||||
case func(w http.ResponseWriter, r *http.Request) bool:
|
||||
if h(w, r) {
|
||||
return false
|
||||
}
|
||||
default:
|
||||
m.ErrorNotImplement(h)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
func _serve_params(msg *ice.Message, path string) {
|
||||
switch ls := strings.Split(path, ice.PS); kit.Select("", ls, 1) {
|
||||
case SHARE:
|
||||
switch ls[2] {
|
||||
case "local":
|
||||
default:
|
||||
msg.Logs("refer", ls[1], ls[2])
|
||||
msg.Option(ls[1], ls[2])
|
||||
}
|
||||
case ice.POD:
|
||||
msg.Logs("refer", ls[1], ls[2])
|
||||
msg.Option(ls[1], ls[2])
|
||||
case "chat":
|
||||
switch kit.Select("", ls, 2) {
|
||||
case ice.POD:
|
||||
msg.Logs("refer", ls[2], ls[3])
|
||||
msg.Option(ls[2], ls[3])
|
||||
}
|
||||
}
|
||||
}
|
||||
func _serve_handle(key string, cmd *ice.Command, msg *ice.Message, w http.ResponseWriter, r *http.Request) {
|
||||
meta := logs.FileLineMeta("")
|
||||
msg.Options(ice.HEIGHT, "480", ice.WIDTH, "320")
|
||||
if u, e := url.Parse(r.Header.Get(Referer)); e == nil {
|
||||
_serve_params(msg, u.Path)
|
||||
kit.Fetch(u.Query(), func(k string, v []string) {
|
||||
msg.Logs("refer", k, v, meta)
|
||||
msg.Optionv(k, v)
|
||||
})
|
||||
gdb.Event(m, SERVE_PARSE, strings.Split(strings.TrimPrefix(u.Path, ice.PS), ice.PS))
|
||||
kit.Fetch(u.Query(), func(k string, v []string) { m.Logs("refer", k, v, meta).Optionv(k, v) })
|
||||
}
|
||||
_serve_params(msg, r.URL.Path)
|
||||
|
||||
// 解析参数
|
||||
switch r.Header.Get(ContentType) {
|
||||
case ContentJSON:
|
||||
defer r.Body.Close()
|
||||
var data ice.Any
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); !msg.Warn(e, ice.ErrNotFound, data) {
|
||||
msg.Logs(mdb.IMPORT, mdb.VALUE, kit.Format(data))
|
||||
msg.Optionv(ice.MSG_USERDATA, data)
|
||||
if e := json.NewDecoder(r.Body).Decode(&data); !m.Warn(e, ice.ErrNotFound, data) {
|
||||
m.Logs(mdb.IMPORT, mdb.VALUE, kit.Format(data))
|
||||
m.Optionv(ice.MSG_USERDATA, data)
|
||||
}
|
||||
kit.Fetch(data, func(key string, value ice.Any) { msg.Optionv(key, value) })
|
||||
|
||||
kit.Fetch(data, func(key string, value ice.Any) { m.Optionv(key, value) })
|
||||
default:
|
||||
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength))))
|
||||
if r.ParseForm(); len(r.PostForm) > 0 {
|
||||
kit.Fetch(r.PostForm, func(k string, v []string) {
|
||||
if len(v) > 1 {
|
||||
msg.Logs("form", k, len(v), kit.Join(v, ice.SP), meta)
|
||||
m.Logs("form", k, len(v), kit.Join(v, ice.SP), meta)
|
||||
} else {
|
||||
msg.Logs("form", k, v, meta)
|
||||
m.Logs("form", k, v, meta)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 请求参数
|
||||
msg.R, msg.W = r, w
|
||||
m.R, m.W = r, w
|
||||
for k, v := range r.Form {
|
||||
if msg.IsCliUA() {
|
||||
if m.IsCliUA() {
|
||||
for i, p := range v {
|
||||
v[i], _ = url.QueryUnescape(p)
|
||||
}
|
||||
}
|
||||
msg.Optionv(k, v)
|
||||
m.Optionv(k, v)
|
||||
}
|
||||
for k, v := range r.PostForm {
|
||||
msg.Optionv(k, v)
|
||||
m.Optionv(k, v)
|
||||
}
|
||||
for _, v := range r.Cookies() {
|
||||
msg.Optionv(v.Name, v.Value)
|
||||
m.Optionv(v.Name, v.Value)
|
||||
}
|
||||
|
||||
// 用户参数
|
||||
msg.Option(ice.MSG_USERWEB, _serve_domain(msg))
|
||||
msg.Option(ice.MSG_USERADDR, kit.Select(r.RemoteAddr, r.Header.Get(ice.MSG_USERADDR)))
|
||||
msg.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP))
|
||||
msg.Option(ice.MSG_USERUA, r.Header.Get(UserAgent))
|
||||
if msg.Option(ice.POD) != "" {
|
||||
msg.Option(ice.MSG_USERPOD, msg.Option(ice.POD))
|
||||
m.Option(ice.MSG_USERADDR, kit.Select(r.RemoteAddr, r.Header.Get(ice.MSG_USERADDR)))
|
||||
m.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP))
|
||||
m.Option(ice.MSG_USERUA, r.Header.Get(UserAgent))
|
||||
if m.Option(ice.MSG_USERWEB, _serve_domain(m)); m.Option(ice.POD) != "" {
|
||||
m.Option(ice.MSG_USERPOD, m.Option(ice.POD))
|
||||
}
|
||||
|
||||
// 会话参数
|
||||
if sessid := msg.Option(CookieName(msg.Option(ice.MSG_USERWEB))); msg.Option(ice.MSG_SESSID) == "" {
|
||||
msg.Option(ice.MSG_SESSID, sessid)
|
||||
if sessid := m.Option(CookieName(m.Option(ice.MSG_USERWEB))); m.Option(ice.MSG_SESSID) == "" {
|
||||
m.Option(ice.MSG_SESSID, sessid)
|
||||
}
|
||||
|
||||
// 解析命令
|
||||
if msg.Optionv(ice.MSG_CMDS) == nil {
|
||||
if m.Optionv(ice.MSG_CMDS) == nil {
|
||||
if p := strings.TrimPrefix(r.URL.Path, key); p != "" {
|
||||
msg.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS))
|
||||
m.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS))
|
||||
}
|
||||
}
|
||||
|
||||
// 执行命令
|
||||
if cmds, ok := _serve_login(msg, key, kit.Simple(msg.Optionv(ice.MSG_CMDS)), w, r); ok {
|
||||
defer func() { msg.Cost(kit.Format("%s %v %v", r.URL.Path, cmds, msg.FormatSize())) }()
|
||||
msg.Option(ice.MSG_OPTS, kit.Filter(kit.Simple(msg.Optionv(ice.MSG_OPTION)), func(k string) bool {
|
||||
return !strings.HasPrefix(k, ice.MSG_SESSID)
|
||||
}))
|
||||
if cmds, ok := _serve_login(m, key, kit.Simple(m.Optionv(ice.MSG_CMDS)), w, r); ok {
|
||||
defer func() { m.Cost(kit.Format("%s %v %v", r.URL.Path, cmds, m.FormatSize())) }()
|
||||
m.Option(ice.MSG_OPTS, kit.Simple(m.Optionv(ice.MSG_OPTION), func(k string) bool { return !strings.HasPrefix(k, ice.MSG_SESSID) }))
|
||||
if len(cmds) > 0 && cmds[0] == ctx.ACTION {
|
||||
msg.Target().Cmd(msg, key, cmds...)
|
||||
m.Target().Cmd(m, key, cmds...)
|
||||
} else {
|
||||
msg.CmdHand(cmd, key, cmds...)
|
||||
m.CmdHand(cmd, key, cmds...)
|
||||
}
|
||||
}
|
||||
|
||||
// 输出响应
|
||||
switch args := msg.Optionv(ice.MSG_ARGS).(type) {
|
||||
case []ice.Any:
|
||||
Render(msg, msg.Option(ice.MSG_OUTPUT), args...)
|
||||
default:
|
||||
Render(msg, msg.Option(ice.MSG_OUTPUT), args)
|
||||
}
|
||||
gdb.Event(m, SERVE_RENDER, m.Option(ice.MSG_OUTPUT))
|
||||
Render(m, m.Option(ice.MSG_OUTPUT), m.Optionv(ice.MSG_ARGS))
|
||||
}
|
||||
func _serve_login(msg *ice.Message, key string, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) {
|
||||
aaa.SessCheck(msg, msg.Option(ice.MSG_SESSID)) // 会话认证
|
||||
|
||||
if msg.Option(ice.MSG_USERNAME) == "" && msg.Config(tcp.LOCALHOST) == ice.TRUE && tcp.IsLocalHost(msg, msg.Option(ice.MSG_USERIP)) {
|
||||
aaa.UserRoot(msg) // 本机认证
|
||||
func _serve_login(m *ice.Message, key string, cmds []string, w http.ResponseWriter, r *http.Request) ([]string, bool) {
|
||||
if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(ice.MSG_USERNAME) == "" {
|
||||
gdb.Event(m, SERVE_LOGIN)
|
||||
}
|
||||
|
||||
if msg.Option(ice.MSG_USERNAME) == "" && msg.Option(SHARE) != "" {
|
||||
switch share := msg.Cmd(SHARE, msg.Option(SHARE)); share.Append(mdb.TYPE) {
|
||||
case STORM, FIELD: // 共享认证
|
||||
msg.Option(ice.MSG_USERNAME, share.Append(aaa.USERNAME))
|
||||
msg.Option(ice.MSG_USERROLE, share.Append(aaa.USERROLE))
|
||||
msg.Option(ice.MSG_USERNICK, share.Append(aaa.USERNICK))
|
||||
}
|
||||
if _, ok := m.Target().Commands[WEB_LOGIN]; ok {
|
||||
return cmds, !m.Target().Cmd(m, WEB_LOGIN, kit.Simple(key, cmds)...).IsErr()
|
||||
} else if gdb.Event(m, SERVE_CHECK, key, cmds); m.IsErr() {
|
||||
return cmds, false
|
||||
} else if m.IsOk() {
|
||||
return cmds, m.SetResult() != nil
|
||||
} else {
|
||||
return cmds, aaa.Right(m, key, cmds)
|
||||
}
|
||||
|
||||
if _, ok := msg.Target().Commands[WEB_LOGIN]; ok { // 单点认证
|
||||
msg.Target().Cmd(msg, WEB_LOGIN, kit.Simple(key, cmds)...)
|
||||
return cmds, !msg.IsErr() && msg.Result(0) != ice.FALSE
|
||||
}
|
||||
|
||||
if aaa.Right(msg.Spawn(), key, cmds) {
|
||||
return cmds, true
|
||||
}
|
||||
|
||||
if msg.Warn(msg.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin, r.URL.Path) {
|
||||
msg.Render(STATUS, http.StatusUnauthorized, ice.ErrNotLogin)
|
||||
return cmds, false // 未登录
|
||||
} else if !aaa.Right(msg, r.URL.Path) {
|
||||
msg.Render(STATUS, http.StatusForbidden, ice.ErrNotRight)
|
||||
return cmds, false // 未授权
|
||||
}
|
||||
return cmds, true
|
||||
}
|
||||
|
||||
const (
|
||||
SERVE_START = "serve.start"
|
||||
SERVE_STOP = "serve.stop"
|
||||
SERVE_START = "serve.start"
|
||||
SERVE_REWRITE = "serve.rewrite"
|
||||
SERVE_PARSE = "serve.parse"
|
||||
SERVE_LOGIN = "serve.login"
|
||||
SERVE_CHECK = "serve.check"
|
||||
SERVE_RENDER = "serve.render"
|
||||
SERVE_STOP = "serve.stop"
|
||||
|
||||
WEB_LOGIN = "_login"
|
||||
SSO = "sso"
|
||||
@ -327,51 +186,62 @@ func init() {
|
||||
SERVE: {Name: "serve name auto start spide", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
cli.NodeInfo(m, ice.Info.PathName, WORKER)
|
||||
for _, p := range []string{LOGIN, SHARE, SPACE, ice.VOLCANOS, ice.INTSHELL, ice.PUBLISH, ice.REQUIRE, ice.HELP, ice.CMD} {
|
||||
m.Cmd(aaa.ROLE, aaa.WHITE, aaa.VOID, p)
|
||||
}
|
||||
gdb.Watch(m, SERVE_START)
|
||||
_serve_rewrite(m)
|
||||
}},
|
||||
SERVE_START: {Name: "source.stdio", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Go(func() {
|
||||
defer m.Cmd(ssh.PROMPT)
|
||||
m.Sleep("30ms", ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.Cmdx(SPACE, DOMAIN))+ice.NL))
|
||||
})
|
||||
}},
|
||||
DOMAIN: {Name: "domain", Help: "域名", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Config(tcp.LOCALHOST, ice.FALSE)
|
||||
ice.Info.Domain = arg[0]
|
||||
}},
|
||||
SPIDE: {Name: "spide", Help: "架构图", Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 { // 模块列表
|
||||
_serve_spide(m, ice.PS, m.Target())
|
||||
ctx.DisplayStorySpide(m, lex.PREFIX, m.ActionKey(), nfs.ROOT, MergeLink(m, ice.PS))
|
||||
}
|
||||
aaa.White(m, LOGIN)
|
||||
}},
|
||||
cli.START: {Name: "start dev proto=http host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) {
|
||||
_serve_start(m)
|
||||
}},
|
||||
SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Go(func() {
|
||||
m.Sleep("30ms", ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.Cmdx(SPACE, DOMAIN))+ice.NL))
|
||||
m.Cmd(ssh.PROMPT)
|
||||
})
|
||||
}},
|
||||
SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[0] != SPIDE_GET {
|
||||
return
|
||||
}
|
||||
switch arg[1] {
|
||||
case ice.PS:
|
||||
if arg[3] == ice.INTSHELL {
|
||||
RenderIndex(m, arg[3])
|
||||
} else {
|
||||
RenderMain(m, "", "")
|
||||
}
|
||||
default:
|
||||
if nfs.ExistsFile(m, arg[2]) {
|
||||
m.RenderDownload(arg[2])
|
||||
}
|
||||
}
|
||||
}},
|
||||
SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Options(ice.HEIGHT, "480", ice.WIDTH, "320")
|
||||
}},
|
||||
SERVE_LOGIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if m.Option(ice.MSG_USERNAME) == "" && m.Config(tcp.LOCALHOST) == ice.TRUE && tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) {
|
||||
aaa.UserRoot(m)
|
||||
}
|
||||
}},
|
||||
DOMAIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 {
|
||||
m.Config(tcp.LOCALHOST, ice.FALSE)
|
||||
ice.Info.Domain = arg[0]
|
||||
}
|
||||
m.Echo(ice.Info.Domain)
|
||||
}},
|
||||
}, mdb.HashAction(
|
||||
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port,dev",
|
||||
tcp.LOCALHOST, ice.TRUE, LOGHEADERS, ice.FALSE,
|
||||
nfs.PATH, kit.Dict(ice.PS, ice.USR_VOLCANOS),
|
||||
ice.VOLCANOS, kit.Dict(nfs.PATH, ice.USR_VOLCANOS, INDEX, "page/index.html",
|
||||
nfs.REPOS, "https://shylinux.com/x/volcanos", nfs.BRANCH, nfs.MASTER,
|
||||
),
|
||||
ice.INTSHELL, kit.Dict(nfs.PATH, ice.USR_INTSHELL, INDEX, ice.INDEX_SH,
|
||||
nfs.REPOS, "https://shylinux.com/x/intshell", nfs.BRANCH, nfs.MASTER,
|
||||
),
|
||||
))},
|
||||
|
||||
PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port,dev", tcp.LOCALHOST, ice.TRUE, LOGHEADERS, ice.FALSE,
|
||||
ice.INTSHELL, kit.Dict(nfs.PATH, ice.USR_INTSHELL, INDEX, ice.INDEX_SH, nfs.REPOS, "https://shylinux.com/x/intshell", nfs.BRANCH, nfs.MASTER),
|
||||
ice.VOLCANOS, kit.Dict(nfs.PATH, ice.USR_VOLCANOS, INDEX, "page/index.html", nfs.REPOS, "https://shylinux.com/x/volcanos", nfs.BRANCH, nfs.MASTER),
|
||||
), ServeAction())},
|
||||
PP(ice.INTSHELL): {Name: "/intshell/", Help: "命令行", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
|
||||
RenderIndex(m, ice.INTSHELL, arg...)
|
||||
}},
|
||||
PP(ice.VOLCANOS): {Name: "/volcanos/", Help: "浏览器", Hand: func(m *ice.Message, arg ...string) {
|
||||
PP(ice.VOLCANOS): {Name: "/volcanos/", Help: "浏览器", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
|
||||
RenderIndex(m, ice.VOLCANOS, arg...)
|
||||
}},
|
||||
PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Hand: func(m *ice.Message, arg ...string) {
|
||||
_share_local(aaa.UserRoot(m), ice.USR_PUBLISH, path.Join(arg...))
|
||||
PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
|
||||
_share_local(m, ice.USR_PUBLISH, path.Join(arg...))
|
||||
}},
|
||||
PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
|
||||
_share_repos(m, path.Join(arg[0], arg[1], arg[2]), arg[3:]...)
|
||||
@ -384,12 +254,12 @@ func init() {
|
||||
m.RenderDownload(p)
|
||||
}},
|
||||
PP(ice.REQUIRE, ice.USR): {Name: "/require/usr/", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
|
||||
_share_local(aaa.UserRoot(m), ice.USR, path.Join(arg...))
|
||||
_share_local(m, ice.USR, path.Join(arg...))
|
||||
}},
|
||||
PP(ice.REQUIRE, ice.SRC): {Name: "/require/src/", Help: "源代码", Hand: func(m *ice.Message, arg ...string) {
|
||||
_share_local(aaa.UserRoot(m), ice.SRC, path.Join(arg...))
|
||||
_share_local(m, ice.SRC, path.Join(arg...))
|
||||
}},
|
||||
PP(ice.HELP): {Name: "/help/", Help: "帮助", Hand: func(m *ice.Message, arg ...string) {
|
||||
PP(ice.HELP): {Name: "/help/", Help: "帮助", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) == 0 {
|
||||
arg = append(arg, "tutor.shy")
|
||||
}
|
||||
@ -409,3 +279,14 @@ func init() {
|
||||
return nil, nil
|
||||
})
|
||||
}
|
||||
func ServeAction() ice.Actions {
|
||||
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
for sub := range m.Target().Commands[m.CommandKey()].Actions {
|
||||
if serveActions[sub] == ice.TRUE {
|
||||
gdb.Watch(m, sub)
|
||||
}
|
||||
}
|
||||
}}}
|
||||
}
|
||||
|
||||
var serveActions = kit.DictList(SERVE_START, SERVE_REWRITE, SERVE_PARSE, SERVE_LOGIN, SERVE_CHECK, SERVE_RENDER, SERVE_STOP)
|
||||
|
@ -147,7 +147,26 @@ func init() {
|
||||
m.EchoQRCode(msg.Option(mdb.LINK))
|
||||
m.ProcessInner()
|
||||
}},
|
||||
}, mdb.HashAction(mdb.FIELD, "time,hash,userrole,username,usernick,river,storm,type,name,text", mdb.EXPIRE, "72h")), Hand: func(m *ice.Message, arg ...string) {
|
||||
SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if kit.Select("", arg, 0) != SHARE {
|
||||
return
|
||||
}
|
||||
switch arg[1] {
|
||||
case "local":
|
||||
default:
|
||||
m.Logs("refer", arg[0], arg[1])
|
||||
m.Option(arg[0], arg[1])
|
||||
}
|
||||
}},
|
||||
SERVE_LOGIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if m.Option(ice.MSG_USERNAME) == "" && m.Option(SHARE) != "" {
|
||||
switch msg := m.Cmd(SHARE, m.Option(SHARE)); msg.Append(mdb.TYPE) {
|
||||
case STORM, FIELD:
|
||||
msg.Tables(func(value ice.Maps) { aaa.SessAuth(m, value) })
|
||||
}
|
||||
}
|
||||
}},
|
||||
}, mdb.HashAction(mdb.FIELD, "time,hash,userrole,username,usernick,river,storm,type,name,text", mdb.EXPIRE, "72h"), ServeAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if ctx.PodCmd(m, SHARE, arg) && m.Length() > 0 {
|
||||
return
|
||||
}
|
||||
|
@ -17,6 +17,66 @@ import (
|
||||
"shylinux.com/x/websocket"
|
||||
)
|
||||
|
||||
func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
msg := m.Cmd(SPIDE, dev)
|
||||
host := msg.Append(kit.Keys(tcp.CLIENT, tcp.HOSTNAME))
|
||||
proto := strings.Replace(msg.Append(kit.Keys(tcp.CLIENT, tcp.PROTOCOL)), ice.HTTP, "ws", 1)
|
||||
uri := kit.ParseURL(kit.MergeURL(proto+"://"+host+PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, SHARE, ice.Info.CtxShare, RIVER, ice.Info.CtxRiver, arg))
|
||||
m.Go(func() {
|
||||
ls := strings.Split(host, ice.DF)
|
||||
args := kit.SimpleKV("type,name,host,port", proto, dev, ls[0], kit.Select(kit.Select("443", "80", proto == "ws"), ls, 1))
|
||||
redial, _ := m.Configv(REDIAL).(ice.Map)
|
||||
a, b, c := kit.Int(redial["a"]), kit.Int(redial["b"]), kit.Int(redial["c"])
|
||||
for i := 0; i >= 0 && i < c; i++ {
|
||||
msg := m.Spawn()
|
||||
msg.Cmd(tcp.CLIENT, tcp.DIAL, args, func(s net.Conn) {
|
||||
if s, _, e := websocket.NewClient(s, uri, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e) {
|
||||
msg.Logs(mdb.CREATE, SPACE, dev, "retry", i, "uri", uri.String())
|
||||
mdb.HashCreate(msg, kit.SimpleKV("", MASTER, dev, host), kit.Dict(mdb.TARGET, s))
|
||||
defer mdb.HashRemove(msg, mdb.NAME, name)
|
||||
if i = 0; _space_handle(msg, true, m.Target().Server().(*Frame), s, dev) {
|
||||
i = -2
|
||||
}
|
||||
}
|
||||
})
|
||||
sleep := time.Duration(rand.Intn(a*(i+1))+b) * time.Millisecond
|
||||
msg.Cost("order", i, "sleep", sleep, "reconnect", dev)
|
||||
if time.Sleep(sleep); mdb.HashSelect(msg).Length() == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
func _space_handle(m *ice.Message, safe bool, frame *Frame, c *websocket.Conn, name string) bool {
|
||||
for {
|
||||
_, b, e := c.ReadMessage()
|
||||
if m.Warn(e, SPACE, name) {
|
||||
break
|
||||
}
|
||||
msg := m.Spawn(b)
|
||||
socket, source, target := c, kit.Simple(msg.Optionv(ice.MSG_SOURCE), name), kit.Simple(msg.Optionv(ice.MSG_TARGET))
|
||||
msg.Log("recv", "%v<-%v %s %v", target, source, msg.Detailv(), msg.FormatMeta())
|
||||
if len(target) == 0 {
|
||||
if msg.Optionv(ice.MSG_HANDLE, ice.TRUE); safe { // 下行命令
|
||||
gdb.Event(msg, SPACE_LOGIN)
|
||||
} else { // 上行请求
|
||||
msg.Option(ice.MSG_USERROLE, aaa.VOID)
|
||||
}
|
||||
msg.Go(func() { _space_exec(msg, source, target, c, name) })
|
||||
} else if mdb.HashSelectDetail(msg, target[0], func(value ice.Map) {
|
||||
if s, ok := value[mdb.TARGET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotValid, target[0]) { // 转发报文
|
||||
socket, source, target = s, source, target[1:]
|
||||
_space_echo(msg, source, target, socket, kit.Select("", target))
|
||||
} else if msg.Option(ice.MSG_HANDLE) != ice.TRUE { // 下发失败
|
||||
source, target = []string{}, kit.Revert(source)[1:]
|
||||
}
|
||||
}) {
|
||||
} else if res, ok := frame.getSend(msg.Option(ice.MSG_TARGET)); !m.Warn(!ok || len(target) != 1) {
|
||||
back(res, msg) // 接收响应
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func _space_domain(m *ice.Message) (link string) {
|
||||
if link = ice.Info.Domain; link == "" {
|
||||
m.Optionv(ice.MSG_OPTS, ice.MSG_USERNAME)
|
||||
@ -36,116 +96,15 @@ func _space_domain(m *ice.Message) (link string) {
|
||||
}
|
||||
return tcp.PublishLocalhost(m, link)
|
||||
}
|
||||
func _space_dial(m *ice.Message, dev, name string, arg ...string) {
|
||||
if strings.HasPrefix(dev, ice.HTTP) {
|
||||
m.Cmd(SPIDE, mdb.CREATE, ice.DEV, dev)
|
||||
dev = ice.DEV
|
||||
}
|
||||
|
||||
msg := m.Cmd(SPIDE, dev)
|
||||
host := msg.Append(kit.Keys(tcp.CLIENT, tcp.HOSTNAME))
|
||||
proto := strings.Replace(msg.Append(kit.Keys(tcp.CLIENT, tcp.PROTOCOL)), ice.HTTP, "ws", 1)
|
||||
uri := kit.MergeURL(proto+"://"+host+PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, SHARE, ice.Info.CtxShare, RIVER, ice.Info.CtxRiver, arg)
|
||||
u := kit.ParseURL(uri)
|
||||
|
||||
m.Go(func() {
|
||||
frame := m.Target().Server().(*Frame)
|
||||
|
||||
ls := strings.Split(host, ice.DF)
|
||||
args := kit.SimpleKV("type,name,host,port", proto, dev, ls[0], kit.Select("443", ls, 1))
|
||||
|
||||
redial, _ := m.Configv(REDIAL).(ice.Map)
|
||||
a, b, c := kit.Int(redial["a"]), kit.Int(redial["b"]), kit.Int(redial["c"])
|
||||
for i := 0; i >= 0 && i < c; i++ {
|
||||
msg := m.Spawn()
|
||||
msg.Cmd(tcp.CLIENT, tcp.DIAL, args, func(s net.Conn) {
|
||||
if s, _, e := websocket.NewClient(s, u, nil, kit.Int(redial["r"]), kit.Int(redial["w"])); !msg.Warn(e) {
|
||||
msg.Logs(mdb.CREATE, SPACE, dev, "retry", i, "uri", uri)
|
||||
mdb.HashCreate(msg, kit.SimpleKV("", MASTER, dev, host), kit.Dict(mdb.TARGET, s))
|
||||
defer mdb.HashRemove(msg, mdb.NAME, name)
|
||||
|
||||
if i = 0; _space_handle(msg, true, frame, s, dev) {
|
||||
i = -2 // 关闭连接
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 断线重连
|
||||
sleep := time.Duration(rand.Intn(a*(i+1))+b) * time.Millisecond
|
||||
msg.Cost("order", i, "sleep", sleep, "reconnect", dev)
|
||||
if time.Sleep(sleep); mdb.HashSelect(msg).Length() == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
func _space_handle(m *ice.Message, safe bool, frame *Frame, c *websocket.Conn, name string) bool {
|
||||
for {
|
||||
_, b, e := c.ReadMessage()
|
||||
if m.Warn(e, SPACE, name) {
|
||||
break
|
||||
}
|
||||
|
||||
socket, msg := c, m.Spawn(b)
|
||||
target := kit.Simple(msg.Optionv(ice.MSG_TARGET))
|
||||
source := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name)
|
||||
msg.Log("recv", "%v<-%v %s %v", target, source, msg.Detailv(), msg.FormatMeta())
|
||||
|
||||
if len(target) == 0 { // 执行命令
|
||||
if msg.Optionv(ice.MSG_HANDLE, ice.TRUE); safe { // 下行命令
|
||||
msg.Option(ice.MSG_USERROLE, kit.Select(msg.Option(ice.MSG_USERROLE), msg.Cmd(aaa.USER, msg.Option(ice.MSG_USERNAME)).Append(aaa.USERROLE)))
|
||||
if msg.Option(ice.MSG_USERROLE) == aaa.VOID && ice.Info.UserName == aaa.TECH {
|
||||
msg.Option(ice.MSG_USERROLE, aaa.TECH) // 演示空间
|
||||
}
|
||||
msg.Auth(aaa.USERROLE, msg.Option(ice.MSG_USERROLE), aaa.USERNAME, msg.Option(ice.MSG_USERNAME))
|
||||
msg.Go(func() { _space_exec(msg, source, target, c, name) })
|
||||
continue
|
||||
}
|
||||
// 上行请求
|
||||
msg.Push(mdb.LINK, kit.MergePOD(_space_domain(msg), name))
|
||||
_space_echo(msg, []string{}, kit.Revert(source)[1:], c, name)
|
||||
continue
|
||||
}
|
||||
|
||||
if mdb.HashSelectDetail(msg, target[0], func(value ice.Map) { // 转发命令
|
||||
if s, ok := value[mdb.TARGET].(*websocket.Conn); ok {
|
||||
socket, source, target = s, source, target[1:]
|
||||
_space_echo(msg, source, target, socket, kit.Select("", target))
|
||||
return // 转发报文
|
||||
}
|
||||
|
||||
if msg.Warn(msg.Option(ice.MSG_HANDLE) == ice.TRUE, ice.ErrNotValid, "already handled") {
|
||||
// 回复失败
|
||||
|
||||
} else { // 下发失败
|
||||
msg.Warn(true, ice.ErrNotFound, target)
|
||||
source, target = []string{}, kit.Revert(source)[1:]
|
||||
}
|
||||
}) {
|
||||
continue
|
||||
}
|
||||
|
||||
if res, ok := frame.getSend(msg.Option(ice.MSG_TARGET)); len(target) != 1 || !ok {
|
||||
if msg.Warn(msg.Option(ice.MSG_HANDLE) == ice.TRUE, ice.ErrNotValid, target) {
|
||||
// 回复失败
|
||||
|
||||
} else { // 下发失败
|
||||
msg.Warn(true, ice.ErrNotFound, target)
|
||||
source, target = []string{}, kit.Revert(source)[1:]
|
||||
}
|
||||
continue
|
||||
} else { // 接收响应
|
||||
m.Sleep30ms()
|
||||
back(res, msg)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, name string) {
|
||||
if aaa.Right(msg, msg.Detailv()) { // 执行命令
|
||||
msg = msg.Cmd()
|
||||
switch msg.Detailv()[0] {
|
||||
case "pwd":
|
||||
msg.Push(mdb.LINK, kit.MergePOD(_space_domain(msg), name))
|
||||
default:
|
||||
if aaa.Right(msg, msg.Detailv()) {
|
||||
msg = msg.Cmd()
|
||||
}
|
||||
}
|
||||
|
||||
msg.Set(ice.MSG_OPTS)
|
||||
_space_echo(msg, []string{}, kit.Revert(source)[1:], c, name)
|
||||
msg.Cost(kit.Format("%v->%v %v %v", source, target, msg.Detailv(), msg.FormatSize()))
|
||||
@ -163,59 +122,47 @@ func _space_echo(msg *ice.Message, source, target []string, c *websocket.Conn, n
|
||||
}
|
||||
func _space_send(m *ice.Message, space string, arg ...string) {
|
||||
if space == "" || space == MYSELF || space == ice.Info.NodeName {
|
||||
m.Cmdy(arg) // 本地命令
|
||||
m.Cmdy(arg)
|
||||
return
|
||||
}
|
||||
|
||||
// 生成参数
|
||||
for _, k := range kit.Simple(m.Optionv(ice.MSG_OPTS)) {
|
||||
kit.Simple(m.Optionv(ice.MSG_OPTS), func(k string) {
|
||||
switch k {
|
||||
case ice.MSG_DETAIL, ice.MSG_CMDS, ice.MSG_SESSID:
|
||||
default:
|
||||
m.Optionv(k, m.Optionv(k))
|
||||
}
|
||||
}
|
||||
})
|
||||
m.Set(ice.MSG_DETAIL, arg...)
|
||||
m.Optionv(ice.MSG_OPTS, m.Optionv(ice.MSG_OPTS))
|
||||
m.Optionv(ice.MSG_OPTION, m.Optionv(ice.MSG_OPTS))
|
||||
m.Set(ice.MSG_DETAIL, arg...)
|
||||
|
||||
// 发送命令
|
||||
frame := m.Target().Server().(*Frame)
|
||||
target, id := kit.Split(space, ice.PT, ice.PT), ""
|
||||
target, id, f := kit.Split(space, ice.PT, ice.PT), "", m.Target().Server().(*Frame)
|
||||
if m.Warn(!mdb.HashSelectDetail(m, target[0], func(value ice.Map) {
|
||||
if socket, ok := value[mdb.TARGET].(*websocket.Conn); !m.Warn(!ok, ice.ErrNotFound, mdb.TARGET) {
|
||||
id = frame.addSend(kit.Format(m.Target().ID()), m)
|
||||
id = f.addSend(kit.Format(m.Target().ID()), m)
|
||||
_space_echo(m, []string{id}, target[1:], socket, target[0])
|
||||
}
|
||||
}), ice.ErrNotFound, space) {
|
||||
return
|
||||
}
|
||||
|
||||
// 返回结果
|
||||
m.Option(TIMEOUT, m.Config(kit.Keys(TIMEOUT, "c")))
|
||||
call(m, m.Option("_async") == "", func(res *ice.Message) {
|
||||
m.Cost(kit.Format("[%v]->%v %v %v", id, target, arg, m.Copy(res).FormatSize()))
|
||||
frame.delSend(id)
|
||||
call(m, m.Config(kit.Keys(TIMEOUT, "c")), func(res *ice.Message) {
|
||||
m.Cost(kit.Format("[%v]->%v %v %v", f.delSend(id), target, arg, m.Copy(res).FormatSize()))
|
||||
})
|
||||
}
|
||||
func _space_fork(m *ice.Message) {
|
||||
buffer, _ := m.Configv(BUFFER).(ice.Map)
|
||||
if s, e := websocket.Upgrade(m.W, m.R, nil, kit.Int(buffer["r"]), kit.Int(buffer["w"])); m.Assert(e) {
|
||||
text := kit.Select(s.RemoteAddr().String(), m.Option(ice.MSG_USERADDR))
|
||||
name := strings.ToLower(m.Option(mdb.NAME, kit.ReplaceAll(kit.Select(text, m.Option(mdb.NAME)), ".", "_", ":", "_")))
|
||||
name := strings.ToLower(m.Option(mdb.NAME, kit.ReplaceAll(kit.Select(text, m.Option(mdb.NAME)), ice.PT, "_", ice.DF, "_")))
|
||||
kind := kit.Select(WORKER, m.Option(mdb.TYPE))
|
||||
args := append([]string{mdb.TYPE, kind, mdb.NAME, name}, m.OptionSimple(SHARE, RIVER, ice.MSG_USERUA)...)
|
||||
|
||||
m.Go(func() {
|
||||
mdb.HashCreate(m, mdb.TEXT, kit.Select(text, m.Option(mdb.TEXT)), args, kit.Dict(mdb.TARGET, s))
|
||||
defer mdb.HashRemove(m, mdb.NAME, name)
|
||||
|
||||
gdb.Event(m, SPACE_OPEN, args)
|
||||
defer gdb.Event(m, SPACE_CLOSE, args)
|
||||
|
||||
switch kind {
|
||||
case CHROME:
|
||||
m.Go(func(msg *ice.Message) { msg.Sleep300ms(SPACE, name, cli.PWD, name) })
|
||||
m.Go(func(msg *ice.Message) { msg.Sleep30ms(SPACE, name, cli.PWD, name) })
|
||||
case WORKER:
|
||||
gdb.Event(m, DREAM_START, args)
|
||||
defer gdb.Event(m, DREAM_STOP, args)
|
||||
@ -241,9 +188,10 @@ const (
|
||||
REDIAL = "redial"
|
||||
TIMEOUT = "timeout"
|
||||
|
||||
SPACE_OPEN = "space.open"
|
||||
SPACE_CLOSE = "space.close"
|
||||
SPACE_START = "space.start"
|
||||
SPACE_OPEN = "space.open"
|
||||
SPACE_LOGIN = "space.login"
|
||||
SPACE_CLOSE = "space.close"
|
||||
SPACE_STOP = "space.stop"
|
||||
)
|
||||
const SPACE = "space"
|
||||
@ -251,26 +199,28 @@ const SPACE = "space"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
PP(SPACE): {Hand: func(m *ice.Message, arg ...string) { _space_fork(m) }},
|
||||
SPACE: {Name: "space name cmd auto invite", Help: "空间站", Actions: ice.MergeActions(ice.Actions{
|
||||
SPACE: {Name: "space name cmd auto", Help: "空间站", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf("", mdb.HASH, "") }},
|
||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { m.Conf("", mdb.HASH, "") }},
|
||||
tcp.DIAL: {Name: "dial dev=ops name", Hand: func(m *ice.Message, arg ...string) {
|
||||
_space_dial(m, m.Option(ice.DEV), kit.Select(ice.Info.NodeName, m.Option(mdb.NAME)), arg...)
|
||||
}},
|
||||
aaa.INVITE: {Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
for _, k := range []string{ice.MISC, ice.CORE, ice.BASE} {
|
||||
m.Cmdy("web.code.publish", ice.CONTEXTS, k)
|
||||
if strings.HasPrefix(m.Option(ice.DEV), ice.HTTP) {
|
||||
m.Cmd(SPIDE, mdb.CREATE, ice.DEV, m.Option(ice.DEV))
|
||||
m.Option(ice.DEV, ice.DEV)
|
||||
}
|
||||
m.EchoScript("shell", "# 共享环境", m.Option(ice.MSG_USERWEB))
|
||||
m.EchoAnchor(m.Option(ice.MSG_USERWEB)).Echo(ice.NL)
|
||||
m.EchoQRCode(m.Option(ice.MSG_USERWEB))
|
||||
_space_dial(m, m.Option(ice.DEV), kit.Select(ice.Info.NodeName, m.Option(mdb.NAME)), arg...)
|
||||
}},
|
||||
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
mdb.HashModify(m, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP)
|
||||
defer mdb.HashRemove(m, m.OptionSimple(mdb.NAME))
|
||||
m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT)
|
||||
}},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ProcessIframe(m, MergePod(m, m.Option(mdb.NAME)), arg...) }},
|
||||
SPACE_LOGIN: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(ice.MSG_USERROLE, kit.Select(m.Option(ice.MSG_USERROLE), m.CmdAppend(aaa.USER, m.Option(ice.MSG_USERNAME), aaa.USERROLE)))
|
||||
if m.Option(ice.MSG_USERROLE) == aaa.VOID && ice.Info.UserName == aaa.VOID {
|
||||
m.Option(ice.MSG_USERROLE, aaa.TECH)
|
||||
}
|
||||
m.Auth(aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERROLE, m.Option(ice.MSG_USERROLE))
|
||||
}},
|
||||
DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch m.Option(mdb.TYPE) {
|
||||
case CHROME:
|
||||
@ -287,19 +237,18 @@ func init() {
|
||||
}
|
||||
}},
|
||||
DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }},
|
||||
OPEN: {Hand: func(m *ice.Message, arg ...string) { ProcessIframe(m, MergePod(m, m.Option(mdb.NAME)), arg...) }},
|
||||
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text",
|
||||
REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000), TIMEOUT, kit.Dict("c", "180s"),
|
||||
BUFFER, kit.Dict("r", ice.MOD_BUFS, "w", ice.MOD_BUFS),
|
||||
), ctx.CmdAction(), DreamAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
), SpaceAction(), DreamAction(), ctx.CmdAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if len(arg) > 0 && arg[0] == ctx.ACTION {
|
||||
gdb.Event(m, DREAM_ACTION, arg)
|
||||
return
|
||||
}
|
||||
if len(arg) > 1 {
|
||||
} else if len(arg) > 1 {
|
||||
_space_send(m, strings.ToLower(arg[0]), kit.Simple(kit.Split(arg[1]), arg[2:])...)
|
||||
return
|
||||
}
|
||||
if mdb.HashSelect(m, arg...); len(arg) > 0 {
|
||||
} else if mdb.HashSelect(m, arg...); len(arg) > 0 {
|
||||
m.Sort("type,name,text")
|
||||
}
|
||||
if m.IsCliUA() {
|
||||
@ -315,6 +264,18 @@ func init() {
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
var spaceActions = kit.DictList(SPACE_START, SPACE_OPEN, SPACE_LOGIN, SPACE_CLOSE, SPACE_STOP)
|
||||
|
||||
func SpaceAction() ice.Actions {
|
||||
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
for sub := range m.Target().Commands[m.CommandKey()].Actions {
|
||||
if spaceActions[sub] == ice.TRUE {
|
||||
gdb.Watch(m, sub)
|
||||
}
|
||||
}
|
||||
}}}
|
||||
}
|
||||
func Space(m *ice.Message, arg ice.Any) []string {
|
||||
if arg == nil || arg == "" || kit.Format(arg) == ice.Info.NodeName {
|
||||
return nil
|
||||
@ -322,28 +283,20 @@ func Space(m *ice.Message, arg ice.Any) []string {
|
||||
return []string{SPACE, kit.Format(arg)}
|
||||
}
|
||||
|
||||
func call(m *ice.Message, sync bool, cb func(*ice.Message)) {
|
||||
func call(m *ice.Message, timeout string, cb func(*ice.Message)) {
|
||||
wait := make(chan bool, 2)
|
||||
|
||||
p := kit.Select("10s", m.Option(TIMEOUT))
|
||||
t := time.AfterFunc(kit.Duration(p), func() {
|
||||
t := time.AfterFunc(kit.Duration(timeout), func() {
|
||||
m.Warn(true, ice.ErrNotValid, m.Detailv())
|
||||
back(m, nil)
|
||||
cb(nil)
|
||||
m.Optionv("_cb", nil)
|
||||
wait <- false
|
||||
})
|
||||
|
||||
m.Optionv("_cb", func(res *ice.Message) {
|
||||
if cb(res); sync {
|
||||
wait <- true
|
||||
t.Stop()
|
||||
}
|
||||
})
|
||||
|
||||
if sync {
|
||||
<-wait
|
||||
} else {
|
||||
cb(res)
|
||||
t.Stop()
|
||||
}
|
||||
wait <- true
|
||||
})
|
||||
<-wait
|
||||
}
|
||||
func back(m *ice.Message, res *ice.Message) {
|
||||
switch cb := m.Optionv("_cb").(type) {
|
||||
|
119
base/web/web.go
119
base/web/web.go
@ -13,106 +13,103 @@ import (
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
"shylinux.com/x/icebergs/base/tcp"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
"shylinux.com/x/toolkits/logs"
|
||||
"shylinux.com/x/toolkits/task"
|
||||
)
|
||||
|
||||
type Frame struct {
|
||||
*ice.Message
|
||||
*http.Client
|
||||
*http.Server
|
||||
*http.ServeMux
|
||||
|
||||
send ice.Messages
|
||||
lock task.Lock
|
||||
send ice.Messages
|
||||
}
|
||||
|
||||
func (frame *Frame) getSend(key string) (*ice.Message, bool) {
|
||||
defer frame.lock.RLock()()
|
||||
msg, ok := frame.send[key]
|
||||
return msg, ok
|
||||
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
||||
f.send = ice.Messages{}
|
||||
return f
|
||||
}
|
||||
func (frame *Frame) addSend(key string, msg *ice.Message) string {
|
||||
defer frame.lock.Lock()()
|
||||
frame.send[key] = msg
|
||||
return key
|
||||
}
|
||||
func (frame *Frame) delSend(key string) {
|
||||
defer frame.lock.Lock()()
|
||||
delete(frame.send, key)
|
||||
}
|
||||
|
||||
func (frame *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _serve_main(frame.Message, w, r) {
|
||||
frame.ServeMux.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
func (frame *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
||||
frame.send = ice.Messages{}
|
||||
return frame
|
||||
}
|
||||
func (frame *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
meta := logs.FileLineMeta("")
|
||||
func (f *Frame) Start(m *ice.Message, arg ...string) bool {
|
||||
f.Message, f.Server = m, &http.Server{Handler: f}
|
||||
list := map[*ice.Context]string{}
|
||||
m.Travel(func(p *ice.Context, c *ice.Context) {
|
||||
if f, ok := c.Server().(*Frame); ok {
|
||||
if f.ServeMux != nil {
|
||||
return
|
||||
f, ok := c.Server().(*Frame)
|
||||
if !ok || f.ServeMux != nil {
|
||||
return
|
||||
}
|
||||
f.ServeMux = http.NewServeMux()
|
||||
msg := m.Spawn(c)
|
||||
if pf, ok := p.Server().(*Frame); ok && pf.ServeMux != nil {
|
||||
route := ice.PS + c.Name + ice.PS
|
||||
msg.Log(ROUTE, "%s <= %s", p.Name, route)
|
||||
pf.Handle(route, http.StripPrefix(path.Dir(route), f))
|
||||
list[c] = path.Join(list[p], route)
|
||||
}
|
||||
m.Confm(SERVE, kit.Keym(nfs.PATH), func(key string, value string) {
|
||||
msg.Log(ROUTE, "%s <- %s <- %s", c.Name, key, value)
|
||||
f.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
|
||||
})
|
||||
for key, cmd := range c.Commands {
|
||||
if key[0] != '/' {
|
||||
continue
|
||||
}
|
||||
f.ServeMux = http.NewServeMux()
|
||||
msg := m.Spawn(c)
|
||||
if pf, ok := p.Server().(*Frame); ok && pf.ServeMux != nil {
|
||||
route := ice.PS + c.Name + ice.PS
|
||||
msg.Log(ROUTE, "%s <= %s", p.Name, route, meta)
|
||||
pf.Handle(route, http.StripPrefix(path.Dir(route), f))
|
||||
list[c] = path.Join(list[p], route)
|
||||
}
|
||||
m.Confm(SERVE, kit.Keym(nfs.PATH), func(key string, value string) {
|
||||
m.Log(ROUTE, "%s <- %s <- %s", c.Name, key, value, meta)
|
||||
f.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
|
||||
})
|
||||
m.Travel(func(p *ice.Context, _c *ice.Context, key string, cmd *ice.Command) {
|
||||
if c != _c || key[0] != '/' {
|
||||
return
|
||||
}
|
||||
msg.Log(ROUTE, "%s <- %s", c.Name, key, meta)
|
||||
ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLine())
|
||||
func(key string, cmd *ice.Command) {
|
||||
msg.Log(ROUTE, "%s <- %s", c.Name, key)
|
||||
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
|
||||
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
|
||||
})
|
||||
})
|
||||
ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLine())
|
||||
}(key, cmd)
|
||||
}
|
||||
})
|
||||
gdb.Event(m, SERVE_START, arg)
|
||||
defer gdb.Event(m, SERVE_STOP)
|
||||
|
||||
frame.Message, frame.Server = m, &http.Server{Handler: frame}
|
||||
switch cb := m.OptionCB("").(type) {
|
||||
case func(http.Handler):
|
||||
cb(frame)
|
||||
cb(f)
|
||||
default:
|
||||
mdb.HashCreate(m, mdb.NAME, WEB, arg, m.OptionSimple(tcp.PROTO, ice.DEV), cli.STATUS, tcp.START)
|
||||
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) {
|
||||
mdb.HashCreate(m, mdb.NAME, WEB, arg, m.OptionSimple(tcp.PROTO, ice.DEV), cli.STATUS, tcp.START)
|
||||
defer mdb.HashModify(m, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP)
|
||||
mdb.HashSelectTarget(m, m.Option(mdb.NAME), func() ice.Any { return l })
|
||||
m.Warn(frame.Server.Serve(l)) // 启动服务
|
||||
m.Warn(f.Server.Serve(l))
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (frame *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
func (f *Frame) Close(m *ice.Message, arg ...string) bool {
|
||||
return true
|
||||
}
|
||||
func (frame *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
|
||||
func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
|
||||
return &Frame{}
|
||||
}
|
||||
func (f *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if _serve_main(f.Message, w, r) {
|
||||
f.ServeMux.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
func (f *Frame) getSend(key string) (*ice.Message, bool) {
|
||||
defer f.lock.RLock()()
|
||||
msg, ok := f.send[key]
|
||||
return msg, ok
|
||||
}
|
||||
func (f *Frame) addSend(key string, msg *ice.Message) string {
|
||||
defer f.lock.Lock()()
|
||||
f.send[key] = msg
|
||||
return key
|
||||
}
|
||||
func (f *Frame) delSend(key string) string {
|
||||
defer f.lock.Lock()()
|
||||
delete(f.send, key)
|
||||
return key
|
||||
}
|
||||
|
||||
const WEB = "web"
|
||||
|
||||
var Index = &ice.Context{Name: WEB, Help: "网络模块"}
|
||||
|
||||
func init() { ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, SHARE, CACHE, SPIDE, ROUTE) }
|
||||
|
||||
func init() {
|
||||
ice.Index.Register(Index, &Frame{}, BROAD, SERVE, SPACE, DREAM, SHARE, CACHE, SPIDE, ROUTE)
|
||||
}
|
||||
func ApiAction(arg ...string) ice.Actions { return ice.Actions{kit.Select(ice.PS, arg, 0): {}} }
|
||||
|
||||
func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) }
|
||||
func PP(arg ...string) string { return P(arg...) + ice.PS }
|
||||
|
@ -8,8 +8,8 @@ import (
|
||||
"shylinux.com/x/icebergs/base/aaa"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/web"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
@ -18,7 +18,17 @@ const POD = "pod"
|
||||
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
web.PP(POD): {Name: "/pod/", Help: "节点", Actions: ice.MergeActions(ctx.CmdAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
POD: {Name: "pod", Help: "节点", Actions: ice.MergeActions(ice.Actions{
|
||||
web.SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch kit.Select("", arg, 0) {
|
||||
case CHAT:
|
||||
for i := 1; i < len(arg)-1; i++ {
|
||||
m.Logs("refer", arg[i], arg[i+1])
|
||||
m.Option(arg[i], arg[i+1])
|
||||
}
|
||||
}
|
||||
}},
|
||||
}, ctx.CmdAction(), web.ServeAction(), web.ApiAction(), aaa.WhiteAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if web.OptionAgentIs(m, "curl", "wget") {
|
||||
aaa.UserRoot(m).Cmdy(web.SHARE_LOCAL, ice.BIN_ICE_BIN, kit.Dict(ice.POD, kit.Select("", arg, 0)))
|
||||
return
|
||||
@ -41,4 +51,4 @@ func init() {
|
||||
|
||||
func RenderWebsite(m *ice.Message, pod string, dir string, arg ...string) *ice.Message {
|
||||
return m.Echo(m.Cmdx(web.Space(m, pod), "web.chat.website", lex.PARSE, dir, arg)).RenderResult()
|
||||
}
|
||||
}
|
||||
|
@ -160,28 +160,6 @@ func init() {
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(mdb.RENDER, mdb.CREATE, nfs.IML, m.PrefixKey())
|
||||
m.Cmd(mdb.ENGINE, mdb.CREATE, nfs.IML, m.PrefixKey())
|
||||
|
||||
web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool {
|
||||
if r.Method != http.MethodGet {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(r.URL.Path, ice.PS) {
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(r.Header.Get(web.UserAgent), "Mozilla") {
|
||||
return false
|
||||
}
|
||||
if strings.HasPrefix(r.URL.Path, CHAT_WEBSITE) {
|
||||
_website_render(m, w, r, kit.Ext(r.URL.Path), m.Cmdx(nfs.CAT, strings.Replace(r.URL.Path, CHAT_WEBSITE, SRC_WEBSITE, 1)), path.Base(r.URL.Path))
|
||||
return true
|
||||
}
|
||||
if m.Cmd(WEBSITE, r.URL.Path, func(value ice.Maps) {
|
||||
_website_render(m, w, r, value[mdb.TYPE], value[mdb.TEXT], path.Base(r.URL.Path))
|
||||
}).Length() > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
}},
|
||||
lex.PARSE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch kit.Ext(arg[0]) {
|
||||
|
@ -159,7 +159,7 @@ func _install_trash(m *ice.Message, arg ...string) {
|
||||
m.Cmd(cli.DAEMON, mdb.REMOVE, kit.Dict(mdb.HASH, value[mdb.HASH]))
|
||||
}
|
||||
})
|
||||
m.Cmd(nfs.TRASH, kit.Path(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT), m.Option(nfs.PATH)))
|
||||
nfs.Trash(m, kit.Path(ice.USR_LOCAL_DAEMON, m.Option(tcp.PORT), m.Option(nfs.PATH)))
|
||||
}
|
||||
func _install_service(m *ice.Message, arg ...string) {
|
||||
arg = kit.Split(path.Base(arg[0]), "_-.")[:1]
|
||||
@ -211,7 +211,7 @@ func init() {
|
||||
gdb.DEBUG: {Name: "debug", Help: "调试", Hand: func(m *ice.Message, arg ...string) {
|
||||
ctx.Process(m, XTERM, []string{mdb.TYPE, "gdb"}, arg...)
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
_install_trash(m, arg...)
|
||||
}},
|
||||
nfs.SOURCE: {Name: "source link path", Help: "源码", Hand: func(m *ice.Message, arg ...string) {
|
||||
@ -250,8 +250,8 @@ func InstallAction(args ...ice.Any) ice.Actions {
|
||||
cli.ORDER: {Name: "order", Help: "加载", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(INSTALL, cli.ORDER, m.Config(nfs.SOURCE), path.Join(_INSTALL, ice.BIN))
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.TRASH, m.Option(nfs.PATH))
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.Trash(m, m.Option(nfs.PATH))
|
||||
}},
|
||||
}
|
||||
}
|
||||
|
@ -26,14 +26,11 @@ const PPROF = "pprof"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
PPROF: {Name: "pprof zone id auto", Help: "性能分析", Actions: ice.MergeActions(ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool {
|
||||
if p := r.URL.Path; strings.HasPrefix(p, "/debug/") {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/debug/", "/code/", -1)
|
||||
m.Debug("rewrite %v -> %v", p, r.URL.Path)
|
||||
}
|
||||
return false
|
||||
})
|
||||
web.SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if strings.HasPrefix(arg[1], "/debug/") {
|
||||
m.R.URL.Path = strings.Replace(m.R.URL.Path, "/debug/", "/code/", -1)
|
||||
m.Debug("rewrite %v -> %v", arg[1], m.R.URL.Path)
|
||||
}
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
@ -61,7 +58,7 @@ func init() {
|
||||
m.Cmd(cli.DAEMON, m.Configv(PPROF), "-http="+p, m.Option(BINNARY), m.Option(nfs.FILE))
|
||||
m.Echo("http://%s/ui/top", p).ProcessInner()
|
||||
}},
|
||||
}, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) {
|
||||
}, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF)), web.ServeAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Fields(len(arg), "time,zone,count,binnary,service,seconds", mdb.ZoneField(m))
|
||||
if mdb.ZoneSelect(m, arg...); len(arg) == 0 {
|
||||
m.EchoAnchor(web.MergeLink(m, "/code/pprof/"))
|
||||
|
@ -120,8 +120,8 @@ func init() {
|
||||
mdb.CREATE: {Name: "create file", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||
_publish_file(m, m.Option(nfs.FILE))
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.TRASH, path.Join(ice.USR_PUBLISH, m.Option(nfs.PATH)))
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.Trash(m, path.Join(ice.USR_PUBLISH, m.Option(nfs.PATH)))
|
||||
}},
|
||||
}, aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Option(nfs.DIR_ROOT, ice.USR_PUBLISH)
|
||||
|
@ -99,8 +99,8 @@ func init() {
|
||||
m.Cmd("", DEVPACK)
|
||||
}
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash path", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.TRASH, arg[0])
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.Trash(m, arg[0])
|
||||
}},
|
||||
nfs.SCRIPT: {Name: "script file=hi/hi.js", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(nfs.DEFS, path.Join(m.Option(nfs.PATH), m.Option(nfs.FILE)), m.Cmdx("", TEMPLATE))
|
||||
|
@ -162,9 +162,9 @@ func init() {
|
||||
_webpack_cache(m.Spawn(), _volcanos(m), true)
|
||||
_webpack_build(m, _publish(m, WEBPACK, m.Option(mdb.NAME)))
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if !strings.Contains(m.Option(nfs.PATH), "page/index") {
|
||||
m.Cmd(nfs.TRASH, m.Option(nfs.PATH))
|
||||
nfs.Trash(m, m.Option(nfs.PATH))
|
||||
}
|
||||
}},
|
||||
}, mdb.HashAction(mdb.SHORT, nfs.PATH, mdb.FIELD, "time,path")), Hand: func(m *ice.Message, arg ...string) {
|
||||
|
@ -82,7 +82,7 @@ func WikiAction(dir string, ext ...string) ice.Actions {
|
||||
return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(nfs.PATH, dir, lex.REGEXP, kit.FileReg(ext...)),
|
||||
web.UPLOAD: {Hand: func(m *ice.Message, arg ...string) { _wiki_upload(m, m.Option(nfs.PATH)) }},
|
||||
nfs.SAVE: {Name: "save path text", Hand: func(m *ice.Message, arg ...string) { _wiki_save(m, m.Option(nfs.PATH), m.Option(mdb.TEXT)) }},
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.TRASH, _wiki_path(m, m.Option(nfs.PATH))) }},
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, _wiki_path(m, m.Option(nfs.PATH))) }},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
case nfs.PATH:
|
||||
|
1
logs.go
1
logs.go
@ -147,6 +147,7 @@ func (m *Message) error(arg ...Any) {
|
||||
}
|
||||
m.Resultv(ErrWarn, kit.Simple(arg))
|
||||
}
|
||||
func (m *Message) IsOk() bool { return m.Result() == OK }
|
||||
func (m *Message) IsErr(arg ...string) bool {
|
||||
return len(arg) == 0 && m.Result(0) == ErrWarn || len(arg) > 0 && m.Result(1) == arg[0]
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ func _server_rewrite(m *ice.Message, p string, r *http.Request) {
|
||||
m.Info("rewrite %v -> %v", p, r.URL.Path) // 访问服务
|
||||
|
||||
} else {
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/x/", "/code/git/repos/", 1)
|
||||
r.URL.Path = strings.Replace(r.URL.Path, "/x/", "/code/git/repository/", 1)
|
||||
m.Info("rewrite %v -> %v", p, r.URL.Path) // 下载源码
|
||||
}
|
||||
}
|
||||
@ -113,16 +113,13 @@ const SERVER = "server"
|
||||
func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
web.WEB_LOGIN: {Hand: func(m *ice.Message, arg ...string) { m.Render(ice.RENDER_VOID) }},
|
||||
"/repos/": {Name: "/repos/", Help: "代码库", Actions: ice.Actions{
|
||||
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
web.AddRewrite(func(p string, w http.ResponseWriter, r *http.Request) bool {
|
||||
if strings.HasPrefix(p, "/x/") {
|
||||
_server_rewrite(m, p, r)
|
||||
}
|
||||
return false
|
||||
})
|
||||
"repository": {Name: "repository", Help: "代码库", Actions: ice.MergeActions(ice.Actions{
|
||||
web.SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if strings.HasPrefix(arg[1], "/x/") {
|
||||
_server_rewrite(m, arg[1], m.R)
|
||||
}
|
||||
}},
|
||||
}, Hand: func(m *ice.Message, arg ...string) {
|
||||
}, web.ServeAction(), web.ApiAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||
if m.Option("go-get") == "1" { // 下载地址
|
||||
p := web.MergeLink(m, "/x/"+path.Join(arg...))
|
||||
m.RenderResult(kit.Format(`<meta name="%s" content="%s">`, "go-import", kit.Format(`%s git %s`, strings.Split(p, "://")[1], p)))
|
||||
@ -164,9 +161,9 @@ func init() {
|
||||
_git_cmd(m, PUSH, "--tags", remote, MASTER)
|
||||
})
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Assert(m.Option(nfs.PATH) != "")
|
||||
m.Cmd(nfs.TRASH, path.Join(ice.USR_LOCAL_REPOS, m.Option(nfs.PATH)))
|
||||
nfs.Trash(m, path.Join(ice.USR_LOCAL_REPOS, m.Option(nfs.PATH)))
|
||||
}},
|
||||
web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch arg[0] {
|
||||
|
@ -306,8 +306,8 @@ func init() {
|
||||
code.PUBLISH: {Name: "publish", Help: "发布", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.MISC, ice.CORE)
|
||||
}},
|
||||
nfs.TRASH: {Name: "trash", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.TRASH, mdb.CREATE, path.Join(_repos_path(m.Option(REPOS)), m.Option(nfs.FILE)))
|
||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||
nfs.Trash(m, path.Join(_repos_path(m.Option(REPOS)), m.Option(nfs.FILE)))
|
||||
}},
|
||||
code.BINPACK: {Name: "binpack", Help: "发布模式", Hand: func(m *ice.Message, arg ...string) {
|
||||
m.Cmd(nfs.LINK, ice.GO_SUM, path.Join(ice.SRC_RELEASE, ice.GO_SUM))
|
||||
|
Loading…
x
Reference in New Issue
Block a user