1
0
forked from x/icebergs

opt web.serve

This commit is contained in:
harveyshao 2022-11-28 20:32:41 +08:00
parent 5ed8e75b40
commit 9c4e24cc5c
16 changed files with 140 additions and 138 deletions

View File

@ -67,16 +67,16 @@ func SessCreate(m *ice.Message, username string) string {
return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username))
}
func SessCheck(m *ice.Message, sessid string) bool {
m.Option("log.caller", logs.FileLine(2))
m.Option("aaa.checker", logs.FileLine(2))
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.Any, arg ...string) {
m.Auth(
func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
return m.Auth(
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"))),
arg, logs.FileLineMeta(kit.Select(logs.FileLine(-1), m.Option("aaa.checker"))),
)
}
func SessLogout(m *ice.Message, arg ...string) {

View File

@ -97,12 +97,12 @@ func UserLogin(m *ice.Message, username, password string) bool {
return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != ""
}
func UserRoot(m *ice.Message, arg ...string) *ice.Message {
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 0))
usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 1))
userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2))
username := kit.Select(ice.Info.UserName, arg, 0)
usernick := kit.Select(UserNick(m, username), arg, 1)
userrole := kit.Select(ROOT, arg, 2)
if len(arg) > 0 {
m.Cmd(USER, mdb.CREATE, username, "", usernick, "", userrole)
ice.Info.UserName = username
m.Cmd(USER, mdb.CREATE, username, "", usernick, "", userrole)
}
return m
return SessAuth(m, kit.Dict(USERNAME, username, USERNICK, usernick, USERROLE, userrole))
}

View File

@ -57,7 +57,7 @@ func _command_search(m *ice.Message, kind, name, text string) {
}
m.PushSearch(ice.CTX, kit.PathName(1), ice.CMD, kit.FileName(1), kit.SimpleKV("", s.Cap(ice.CTX_FOLLOW), cmd.Name, cmd.Help),
CONTEXT, s.Cap(ice.CTX_FOLLOW), COMMAND, key, INDEX, kit.Keys(s.Cap(ice.CTX_FOLLOW), key),
mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.GetFileLine()),
mdb.HELP, cmd.Help, nfs.FILE, FileURI(cmd.GetFileLines()),
)
})
}
@ -186,7 +186,7 @@ func GetFileCmd(dir string) string {
}
func GetCmdFile(m *ice.Message, cmds string) (file string) {
m.Search(cmds, func(key string, cmd *ice.Command) {
if file = strings.TrimPrefix(FileURI(kit.Split(cmd.GetFileLine(), ice.DF)[0]), "/require/"); !nfs.ExistsFile(m, file) {
if file = strings.TrimPrefix(FileURI(kit.Split(cmd.GetFileLines(), ice.DF)[0]), "/require/"); !nfs.ExistsFile(m, file) {
file = path.Join(ice.ISH_PLUGED, file)
}
})
@ -197,7 +197,7 @@ func TravelCmd(m *ice.Message, cb func(key, file, line string)) *ice.Message {
if IsOrderCmd(key) {
return
}
if ls := kit.Split(cmd.GetFileLine(), ice.DF); !m.Warn(len(ls) == 0, ice.ErrNotFound, key) {
if ls := kit.Split(cmd.GetFileLines(), ice.DF); !m.Warn(len(ls) == 0, ice.ErrNotFound, key) {
cb(kit.Keys(s.Cap(ice.CTX_FOLLOW), key), strings.TrimPrefix(ls[0], kit.Path("")+ice.PS), kit.Select("1", ls, 1))
}
})

View File

@ -4,6 +4,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
const (
@ -19,8 +20,9 @@ func init() {
mdb.ZoneInsert(m, m.OptionSimple(EVENT, ice.CMD))
}},
HAPPEN: {Name: "happen event", Help: "触发", Hand: func(m *ice.Message, arg ...string) {
defer m.Cost()
mdb.ZoneSelect(m.Spawn(ice.OptionFields("")), m.Option(EVENT)).Tables(func(value ice.Maps) {
m.Cmdy(kit.Split(value[ice.CMD]), m.Option(EVENT), arg[2:], ice.OptionFields("")).Cost()
m.Cmdy(kit.Split(value[ice.CMD]), m.Option(EVENT), arg[2:], ice.OptionFields(""))
})
}},
}, mdb.ZoneAction(mdb.SHORT, EVENT, mdb.FIELD, "time,id,cmd"))},
@ -28,13 +30,23 @@ func init() {
}
func EventAction(arg ...string) ice.Actions {
return ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, args ...string) {
ice.CTX_INIT: {Hand: func(m *ice.Message, _ ...string) {
for _, v := range arg {
Watch(m, v)
}
}},
}
}
func EventsAction(arg ...string) ice.Actions {
list := kit.DictList(arg...)
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
for sub := range m.Target().Commands[m.CommandKey()].Actions {
if list[sub] == ice.TRUE {
Watch(m, sub)
}
}
}}}
}
func Watch(m *ice.Message, key string, arg ...string) *ice.Message {
if len(arg) == 0 {
arg = append(arg, m.PrefixKey())
@ -42,5 +54,5 @@ func Watch(m *ice.Message, key string, arg ...string) *ice.Message {
return m.Cmd(EVENT, LISTEN, EVENT, key, ice.CMD, kit.Join(arg, ice.SP))
}
func Event(m *ice.Message, key string, arg ...ice.Any) *ice.Message {
return m.Cmdy(EVENT, HAPPEN, EVENT, kit.Select(kit.Keys(m.CommandKey(), m.ActionKey()), key), arg)
return m.Cmdy(EVENT, HAPPEN, EVENT, kit.Select(kit.Keys(m.CommandKey(), m.ActionKey()), key), arg, logs.FileLineMeta(logs.FileLine(-1)))
}

View File

@ -1,7 +1,6 @@
package web
import (
"encoding/json"
"net/http"
"net/url"
"path"
@ -17,121 +16,82 @@ import (
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
func _serve_start(m *ice.Message) {
aaa.UserRoot(m, m.Option(aaa.USERNAME), m.Option(aaa.USERNICK))
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)
m.Sleep30ms().Go(func() { m.Cmd(BROAD, SERVE) })
for _, v := range kit.Split(m.Option(ice.DEV)) {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, v, 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())
const (
X_REAL_IP = "X-Real-Ip"
X_REAL_PORT = "X-Real-Port"
X_FORWARDED_FOR = "X-Forwarded-For"
INDEX_MODULE = "Index-Module"
MOZILLA = "Mozilla/5.0"
)
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"))
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+ice.DF+r.Header.Get(X_REAL_PORT))
}
} else if ip := r.Header.Get("X-Forwarded-For"); ip != "" {
} 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])
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, ice.DF)[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)
if m.Logs(r.Method, r.Header.Get(ice.MSG_USERIP), r.URL.String()); m.Config(LOGHEADERS) == ice.TRUE {
kit.Fetch(r.Header, func(k string, v []string) { m.Logs("Header", k, v) })
}
repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), "Mozilla/5.0"))
repos := kit.Select(ice.INTSHELL, ice.VOLCANOS, strings.Contains(r.Header.Get(UserAgent), MOZILLA))
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 != "" {
return p
}
if p := m.R.Header.Get("X-Host"); p != "" {
return p
}
if m.R.Method == SPIDE_POST {
if p := m.R.Header.Get(Referer); p != "" {
return p
}
}
if m.R.TLS == nil {
return kit.Format("http://%s", m.R.Host)
} else {
return kit.Format("https://%s", m.R.Host)
}
}
func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.ResponseWriter, r *http.Request) {
meta := logs.FileLineMeta("")
if u, e := url.Parse(r.Header.Get(Referer)); e == nil {
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) })
kit.Fetch(u.Query(), func(k string, v []string) { m.Logs("Refer", k, v).Optionv(k, v) })
}
for k, v := range kit.ParseQuery(r.URL.RawQuery) {
if m.IsCliUA() {
v = kit.Simple(v, func(v string) (string, error) { return url.QueryUnescape(v) })
}
m.Optionv(k, v)
}
switch r.Header.Get(ContentType) {
case ContentJSON:
defer r.Body.Close()
var data ice.Any
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) { m.Optionv(key, value) })
data := kit.UnMarshal(r.Body)
m.Logs(mdb.IMPORT, mdb.VALUE, kit.Format(data)).Optionv(ice.MSG_USERDATA, data)
kit.Fetch(data, func(k string, v ice.Any) { m.Optionv(k, v) })
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 {
m.Logs("form", k, len(v), kit.Join(v, ice.SP), meta)
} else {
m.Logs("form", k, v, meta)
}
})
}
kit.Fetch(r.PostForm, func(k string, v []string) { m.Logs("Form", k, kit.Join(v, ice.SP)).Optionv(k, v) })
}
m.R, m.W = r, w
for k, v := range r.Form {
if m.IsCliUA() {
for i, p := range v {
v[i], _ = url.QueryUnescape(p)
}
}
m.Optionv(k, v)
}
for k, v := range r.PostForm {
m.Optionv(k, v)
}
for _, v := range r.Cookies() {
m.Optionv(v.Name, v.Value)
}
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))
kit.Fetch(r.Cookies(), func(k, v string) { m.Optionv(k, v) })
m.OptionDefault(ice.HEIGHT, "480", ice.WIDTH, "320")
m.Option(ice.MSG_USERUA, r.Header.Get(UserAgent))
m.Option(ice.MSG_USERIP, r.Header.Get(ice.MSG_USERIP))
m.Option(ice.MSG_USERADDR, kit.Select(r.RemoteAddr, r.Header.Get(ice.MSG_USERADDR)))
if m.Option(ice.MSG_USERWEB, _serve_domain(m)); m.Option(ice.POD) != "" {
m.Option(ice.MSG_USERPOD, m.Option(ice.POD))
}
if sessid := m.Option(CookieName(m.Option(ice.MSG_USERWEB))); m.Option(ice.MSG_SESSID) == "" {
m.Option(ice.MSG_SESSID, sessid)
}
m.Option(ice.MSG_SESSID, m.Option(CookieName(m.Option(ice.MSG_USERWEB))))
if m.Optionv(ice.MSG_CMDS) == nil {
if p := strings.TrimPrefix(r.URL.Path, key); p != "" {
m.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS))
@ -140,8 +100,8 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
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 {
m.Target().Cmd(m, key, cmds...)
if m.Detailv(m.PrefixKey(), cmds); len(cmds) > 1 && cmds[0] == ctx.ACTION {
m.ActionHand(cmd, key, cmds[1], cmds[2:]...)
} else {
m.CmdHand(cmd, key, cmds...)
}
@ -149,6 +109,17 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response
gdb.Event(m, SERVE_RENDER, m.Option(ice.MSG_OUTPUT))
Render(m, m.Option(ice.MSG_OUTPUT), m.Optionv(ice.MSG_ARGS))
}
func _serve_domain(m *ice.Message) string {
return kit.GetValid(func() string {
return ice.Info.Domain
}, func() string {
return m.R.Header.Get("X-Host")
}, func() string {
return kit.Select("", m.R.Header.Get(Referer), m.R.Method == SPIDE_POST)
}, func() string {
return kit.Format("%s://%s", kit.Select("https", ice.HTTP, m.R.TLS == nil), m.R.Host)
})
}
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)
@ -174,27 +145,25 @@ const (
SERVE_STOP = "serve.stop"
WEB_LOGIN = "_login"
DOMAIN = "domain"
INDEX = "index"
SSO = "sso"
DOMAIN = "domain"
INDEX = "index"
)
const SERVE = "serve"
func init() {
Index.MergeCommands(ice.Commands{
SERVE: {Name: "serve name auto start spide", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
SERVE: {Name: "serve name auto start", Help: "服务器", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
cli.NodeInfo(m, ice.Info.PathName, WORKER)
aaa.White(m, LOGIN)
}},
cli.START: {Name: "start dev proto=http host port=9020 nodename username usernick", Hand: func(m *ice.Message, arg ...string) {
cli.START: {Name: "start dev name=web 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)
m.Sleep("30ms", ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.Cmdx(SPACE, DOMAIN))+ice.NL)).Cmd(ssh.PROMPT)
})
}},
SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
@ -215,7 +184,6 @@ func init() {
}
}},
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)) {
@ -230,7 +198,7 @@ func init() {
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,
mdb.SHORT, mdb.NAME, mdb.FIELD, "time,status,name,proto,host,port", 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())},
@ -269,24 +237,16 @@ func init() {
m.Cmdy("web.chat./cmd/", arg)
}},
})
ice.AddMerges(func(c *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
ice.AddMerges(func(ctx *ice.Context, key string, cmd *ice.Command, sub string, action *ice.Action) (ice.Handler, ice.Handler) {
if strings.HasPrefix(sub, ice.PS) {
if sub = kit.Select(sub, PP(key), sub == ice.PS); action.Hand == nil {
action.Hand = func(m *ice.Message, arg ...string) { m.Cmdy(key, arg) }
}
c.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Hand: action.Hand}
ctx.Commands[sub] = &ice.Command{Name: sub, Help: cmd.Help, Actions: cmd.Actions, Hand: action.Hand}
}
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)
}
}
}}}
return gdb.EventsAction(SERVE_START, SERVE_REWRITE, SERVE_PARSE, SERVE_LOGIN, SERVE_CHECK, SERVE_RENDER, SERVE_STOP)
}
var serveActions = kit.DictList(SERVE_START, SERVE_REWRITE, SERVE_PARSE, SERVE_LOGIN, SERVE_CHECK, SERVE_RENDER, SERVE_STOP)

View File

@ -19,8 +19,7 @@ import (
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)
proto, host := strings.Replace(msg.Append(kit.Keys(tcp.CLIENT, tcp.PROTOCOL)), ice.HTTP, "ws", 1), msg.Append(kit.Keys(tcp.CLIENT, tcp.HOSTNAME))
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)
@ -40,10 +39,8 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
}
})
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
}
msg.Cost("order", i, "sleep", sleep, "redial", dev)
time.Sleep(sleep)
}
})
}

View File

@ -55,9 +55,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
func(key string, cmd *ice.Command) {
msg.Log(ROUTE, "%s <- %s", c.Name, key)
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
msg.TryCatch(msg.Spawn(), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
m.TryCatch(m.Spawn(w, r, c, cmd, key), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
})
ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLine())
ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLines())
}(key, cmd)
}
})
@ -68,7 +68,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
cb(f)
default:
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)
mdb.HashCreate(m, m.OptionSimple(mdb.NAME, tcp.PROTO), arg, cli.STATUS, tcp.START)
defer mdb.HashModify(m, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP)
m.Warn(f.Server.Serve(l))
})

View File

@ -312,6 +312,7 @@ const ( // mdb
)
const ( // ice
MDB = "mdb"
GDB = "gdb"
AAA = "aaa"
CLI = "cli"
)

View File

@ -81,6 +81,7 @@ func init() {
ctx.Run(m, arg...)
}},
}, mdb.HashAction(), ctx.CmdAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) {
m.Debug(m.FormatChain())
if len(arg) > 0 && arg[0] == ctx.ACTION {
m.Option(mdb.TYPE, m.Cmd("", m.Option(mdb.HASH)).Append(mdb.TYPE))
gdb.Event(m, FAVOR_ACTION, arg)

View File

@ -26,9 +26,6 @@ func _header_share(m *ice.Message, arg ...string) {
if m.Warn(m.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin, "没有登录") {
return
}
if m.Warn(m.Option(web.SHARE) != "", ice.ErrNotRight, "没有权限") {
return
}
for i := 0; i < len(arg)-1; i += 2 {
m.Option(arg[i], arg[i+1])
}

View File

@ -92,6 +92,14 @@ func Run(arg ...string) string {
arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
}
Pulse.meta[MSG_DETAIL] = arg
kit.Fetch(kit.Sort(os.Environ()), func(env string) {
if ls := strings.SplitN(env, EQ, 2); strings.ToLower(ls[0]) == ls[0] && ls[0] != "_" {
Pulse.Option(ls[0], ls[1])
}
})
if Pulse._cmd == nil {
Pulse._cmd = &Command{RawHand: logs.FileLines(3)}
}
switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
case SERVE, SPACE:
if Index.Start(Pulse, arg...) {

10
logs.go
View File

@ -5,6 +5,7 @@ import (
"runtime"
"strings"
"time"
"unicode"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
@ -75,6 +76,9 @@ func (m *Message) Log(level string, str string, arg ...Any) *Message {
}
func (m *Message) Logs(level string, arg ...Any) *Message {
str, meta := m.join(arg...)
if unicode.IsUpper([]rune(level)[0]) {
meta = []Any{logs.FileLineMeta("")}
}
return m.log(level, str, meta...)
}
@ -84,8 +88,9 @@ func (m *Message) Auth(arg ...Any) *Message {
}
func (m *Message) Cost(arg ...Any) *Message {
str, meta := m.join(arg...)
if len(arg) == 0 {
if str == "" || len(arg) == 0 {
str = kit.Join(m.meta[MSG_DETAIL], SP)
meta = []Any{logs.FileLineMeta(m._fileline())}
}
list := []string{m.FormatCost(), str}
return m.log(LOG_COST, kit.Join(list, SP), meta...)
@ -187,11 +192,12 @@ func (m *Message) FormatChain() string {
meta := append([]string{}, NL)
for i := len(ms) - 1; i >= 0; i-- {
msg := ms[i]
meta = append(meta, kit.Format("%s %s:%d %v %s:%d %v %s:%d %v %s:%d %v", msg.FormatPrefix(),
meta = append(meta, kit.Format("%s %s:%d %v %s:%d %v %s:%d %v %s:%d %v %s", msg.FormatPrefix(),
MSG_DETAIL, len(msg.meta[MSG_DETAIL]), msg.meta[MSG_DETAIL],
MSG_OPTION, len(msg.meta[MSG_OPTION]), msg.meta[MSG_OPTION],
MSG_APPEND, len(msg.meta[MSG_APPEND]), msg.meta[MSG_APPEND],
MSG_RESULT, len(msg.meta[MSG_RESULT]), msg.meta[MSG_RESULT],
msg._cmd.GetFileLine(),
))
for _, k := range msg.meta[MSG_OPTION] {
if v, ok := msg.meta[k]; ok {

View File

@ -393,6 +393,9 @@ func (m *Message) Detail(arg ...Any) string {
return kit.Select("", m.meta[MSG_DETAIL], 0)
}
func (m *Message) Detailv(arg ...Any) []string {
if len(arg) > 0 {
m.meta[MSG_DETAIL] = kit.Simple(arg...)
}
return m.meta[MSG_DETAIL]
}
func (m *Message) Options(arg ...Any) Any {

22
misc.go
View File

@ -166,17 +166,23 @@ func (m *Message) Design(action Any, help string, input ...Any) {
}
func (m *Message) _fileline() string {
switch m.target.Name {
case MDB, AAA:
case MDB, GDB, AAA:
return m._source
default:
return m._target
}
}
func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message {
if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.GetFileLines()) {
return m.Target()._action(m, cmd, key, sub, action, arg...)
}
return m
}
func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
if m._key, m._cmd = key, cmd; cmd == nil {
return m
}
m._target = kit.Join(kit.Slice(kit.Split(cmd.GetFileLine(), PS), -3), PS)
m._target = kit.Join(kit.Slice(kit.Split(cmd.GetFileLines(), PS), -3), PS)
if fileline := m._fileline(); key == SELECT {
m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline))
} else {
@ -279,7 +285,7 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
m.Cmdy(kit.Split(h.Name), arg)
return m
}
if m._sub = sub; len(h.List) > 0 && sub != SEARCH {
if m._key, m._cmd, m._sub = key, cmd, sub; len(h.List) > 0 && sub != SEARCH {
order := false
for i, v := range h.List {
name := kit.Format(kit.Value(v, NAME))
@ -288,13 +294,17 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
order = true
}
if order {
m.Option(name, kit.Select(value, arg, i))
} else {
m.OptionDefault(name, value)
value = kit.Select(value, arg, i)
}
if value != "" {
m.Option(name, value)
}
}
if !order {
for i := 0; i < len(arg)-1; i += 2 {
if strings.HasPrefix(arg[i], PS) {
break
}
m.Option(arg[i], arg[i+1])
}
}

View File

@ -99,7 +99,7 @@ func init() {
switch args := _tags_split(m.Option(PRE), m.Option(COL)); args[0] {
case "field":
m.Search(kit.Select(args[1], args, 2), func(key string, cmd *ice.Command) {
ls := kit.Split(cmd.GetFileLine(), ":")
ls := kit.Split(cmd.GetFileLines(), ":")
m.Echo("vi +%s %s", ls[1], ls[0])
})
case "qrcode":

13
type.go
View File

@ -91,7 +91,12 @@ func (c *Context) PrefixKey(arg ...string) string {
return kit.Keys(c.Cap(CTX_FOLLOW), arg)
}
func (c *Command) GetFileLine() string {
if c.RawHand != nil {
return kit.Join(kit.Slice(kit.Split(c.GetFileLines(), PS), -3), PS)
}
func (c *Command) GetFileLines() string {
if c == nil {
return ""
} else if c.RawHand != nil {
switch h := c.RawHand.(type) {
case string:
return h
@ -348,11 +353,11 @@ func (m *Message) Spawn(arg ...Any) *Message {
json.Unmarshal(val, &msg.meta)
case Option:
msg.Option(val.Name, val.Value)
case Map:
case Maps:
for k, v := range val {
msg.Option(k, v)
}
case Maps:
case Map:
for k, v := range val {
msg.Option(k, v)
}
@ -362,6 +367,8 @@ func (m *Message) Spawn(arg ...Any) *Message {
msg.R = val
case *Context:
msg.target = val
case *Command:
msg._cmd = val
case string:
msg._key = val
}