1
0
mirror of https://shylinux.com/x/icebergs synced 2025-06-26 10:27:31 +08:00

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)) return m.Option(ice.MSG_SESSID, m.Cmdx(SESS, mdb.CREATE, username))
} }
func SessCheck(m *ice.Message, sessid string) bool { 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) m.Options(ice.MSG_USERNAME, "", ice.MSG_USERNICK, "", ice.MSG_USERROLE, VOID)
return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != "" return sessid != "" && m.Cmdy(SESS, CHECK, sessid).Option(ice.MSG_USERNAME) != ""
} }
func SessAuth(m *ice.Message, value ice.Any, arg ...string) { func SessAuth(m *ice.Message, value ice.Any, arg ...string) *ice.Message {
m.Auth( return m.Auth(
USERNAME, m.Option(ice.MSG_USERNAME, kit.Value(value, USERNAME)), USERNAME, m.Option(ice.MSG_USERNAME, kit.Value(value, USERNAME)),
USERNICK, m.Option(ice.MSG_USERNICK, kit.Value(value, USERNICK)), USERNICK, m.Option(ice.MSG_USERNICK, kit.Value(value, USERNICK)),
USERROLE, m.Option(ice.MSG_USERROLE, kit.Value(value, USERROLE)), 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) { 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) != "" return m.Cmdy(USER, LOGIN, username, password).Option(ice.MSG_USERNAME) != ""
} }
func UserRoot(m *ice.Message, arg ...string) *ice.Message { func UserRoot(m *ice.Message, arg ...string) *ice.Message {
username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 0)) username := kit.Select(ice.Info.UserName, arg, 0)
usernick := m.Option(ice.MSG_USERNICK, kit.Select(UserNick(m, username), arg, 1)) usernick := kit.Select(UserNick(m, username), arg, 1)
userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2)) userrole := kit.Select(ROOT, arg, 2)
if len(arg) > 0 { if len(arg) > 0 {
m.Cmd(USER, mdb.CREATE, username, "", usernick, "", userrole)
ice.Info.UserName = username 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), 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), 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) { func GetCmdFile(m *ice.Message, cmds string) (file string) {
m.Search(cmds, func(key string, cmd *ice.Command) { 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) 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) { if IsOrderCmd(key) {
return 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)) 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" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
) )
const ( const (
@ -19,8 +20,9 @@ func init() {
mdb.ZoneInsert(m, m.OptionSimple(EVENT, ice.CMD)) mdb.ZoneInsert(m, m.OptionSimple(EVENT, ice.CMD))
}}, }},
HAPPEN: {Name: "happen event", Help: "触发", Hand: func(m *ice.Message, arg ...string) { 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) { 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"))}, }, mdb.ZoneAction(mdb.SHORT, EVENT, mdb.FIELD, "time,id,cmd"))},
@ -28,13 +30,23 @@ func init() {
} }
func EventAction(arg ...string) ice.Actions { func EventAction(arg ...string) ice.Actions {
return 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 { for _, v := range arg {
Watch(m, v) 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 { func Watch(m *ice.Message, key string, arg ...string) *ice.Message {
if len(arg) == 0 { if len(arg) == 0 {
arg = append(arg, m.PrefixKey()) 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)) 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 { 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 package web
import ( import (
"encoding/json"
"net/http" "net/http"
"net/url" "net/url"
"path" "path"
@ -17,121 +16,82 @@ import (
"shylinux.com/x/icebergs/base/ssh" "shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
) )
func _serve_start(m *ice.Message) { 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 { 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)) 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.Target().Start(m, m.OptionSimple(tcp.HOST, tcp.PORT)...)
m.Sleep300ms().Go(func() { m.Cmd(BROAD, SERVE) }) m.Sleep30ms().Go(func() { m.Cmd(BROAD, SERVE) })
for _, k := range kit.Split(m.Option(ice.DEV)) { for _, v := range kit.Split(m.Option(ice.DEV)) {
m.Cmd(SPACE, tcp.DIAL, ice.DEV, k, mdb.NAME, ice.Info.NodeName) 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 { func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
if r.Header.Get("Index-Module") == "" { const (
r.Header.Set("Index-Module", m.Prefix()) 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 { } else {
return true return true
} }
if ip := r.Header.Get("X-Real-Ip"); ip != "" { if ip := r.Header.Get(X_REAL_IP); ip != "" {
if r.Header.Set(ice.MSG_USERIP, ip); r.Header.Get("X-Real-Port") != "" { 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")) 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]) r.Header.Set(ice.MSG_USERIP, kit.Split(ip)[0])
} else if strings.HasPrefix(r.RemoteAddr, "[") { } else if strings.HasPrefix(r.RemoteAddr, "[") {
r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:]) r.Header.Set(ice.MSG_USERIP, strings.Split(r.RemoteAddr, "]")[0][1:])
} else { } 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("") if m.Logs(r.Method, r.Header.Get(ice.MSG_USERIP), r.URL.String()); m.Config(LOGHEADERS) == ice.TRUE {
m.Info("%s %s %s", r.Header.Get(ice.MSG_USERIP), r.Method, r.URL, meta) kit.Fetch(r.Header, func(k string, v []string) { m.Logs("Header", k, v) })
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")) 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) != "" { 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))...) Render(msg, msg.Option(ice.MSG_OUTPUT), kit.List(msg.Optionv(ice.MSG_ARGS))...)
return false return false
} }
return true 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) { 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 { 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)) 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) { switch r.Header.Get(ContentType) {
case ContentJSON: case ContentJSON:
defer r.Body.Close() data := kit.UnMarshal(r.Body)
var data ice.Any m.Logs(mdb.IMPORT, mdb.VALUE, kit.Format(data)).Optionv(ice.MSG_USERDATA, data)
if e := json.NewDecoder(r.Body).Decode(&data); !m.Warn(e, ice.ErrNotFound, data) { kit.Fetch(data, func(k string, v ice.Any) { m.Optionv(k, v) })
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) })
default: default:
r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength)))) 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) { m.Logs("Form", k, kit.Join(v, ice.SP)).Optionv(k, v) })
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)
}
})
}
} }
m.R, m.W = r, w kit.Fetch(r.Cookies(), func(k, v string) { m.Optionv(k, v) })
for k, v := range r.Form { m.OptionDefault(ice.HEIGHT, "480", ice.WIDTH, "320")
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))
m.Option(ice.MSG_USERUA, r.Header.Get(UserAgent)) 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) != "" { if m.Option(ice.MSG_USERWEB, _serve_domain(m)); m.Option(ice.POD) != "" {
m.Option(ice.MSG_USERPOD, 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, m.Option(CookieName(m.Option(ice.MSG_USERWEB))))
m.Option(ice.MSG_SESSID, sessid)
}
if m.Optionv(ice.MSG_CMDS) == nil { if m.Optionv(ice.MSG_CMDS) == nil {
if p := strings.TrimPrefix(r.URL.Path, key); p != "" { if p := strings.TrimPrefix(r.URL.Path, key); p != "" {
m.Optionv(ice.MSG_CMDS, strings.Split(p, ice.PS)) 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 { 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())) }() 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) })) 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 { if m.Detailv(m.PrefixKey(), cmds); len(cmds) > 1 && cmds[0] == ctx.ACTION {
m.Target().Cmd(m, key, cmds...) m.ActionHand(cmd, key, cmds[1], cmds[2:]...)
} else { } else {
m.CmdHand(cmd, key, cmds...) 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)) gdb.Event(m, SERVE_RENDER, m.Option(ice.MSG_OUTPUT))
Render(m, m.Option(ice.MSG_OUTPUT), m.Optionv(ice.MSG_ARGS)) 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) { 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) == "" { if aaa.SessCheck(m, m.Option(ice.MSG_SESSID)); m.Option(ice.MSG_USERNAME) == "" {
gdb.Event(m, SERVE_LOGIN) gdb.Event(m, SERVE_LOGIN)
@ -174,27 +145,25 @@ const (
SERVE_STOP = "serve.stop" SERVE_STOP = "serve.stop"
WEB_LOGIN = "_login" WEB_LOGIN = "_login"
DOMAIN = "domain"
INDEX = "index"
SSO = "sso" SSO = "sso"
DOMAIN = "domain"
INDEX = "index"
) )
const SERVE = "serve" const SERVE = "serve"
func init() { func init() {
Index.MergeCommands(ice.Commands{ 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) { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
cli.NodeInfo(m, ice.Info.PathName, WORKER) cli.NodeInfo(m, ice.Info.PathName, WORKER)
aaa.White(m, LOGIN) 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(m)
}}, }},
SERVE_START: {Hand: func(m *ice.Message, arg ...string) { SERVE_START: {Hand: func(m *ice.Message, arg ...string) {
m.Go(func() { 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.Sleep("30ms", ssh.PRINTF, kit.Dict(nfs.CONTENT, "\r"+ice.Render(m, ice.RENDER_QRCODE, m.Cmdx(SPACE, DOMAIN))+ice.NL)).Cmd(ssh.PROMPT)
m.Cmd(ssh.PROMPT)
}) })
}}, }},
SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) { SERVE_REWRITE: {Hand: func(m *ice.Message, arg ...string) {
@ -215,7 +184,6 @@ func init() {
} }
}}, }},
SERVE_PARSE: {Hand: func(m *ice.Message, arg ...string) { 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) { 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)) { 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) m.Echo(ice.Info.Domain)
}}, }},
}, mdb.HashAction( }, 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.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), 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())}, ), ServeAction())},
@ -269,24 +237,16 @@ func init() {
m.Cmdy("web.chat./cmd/", arg) 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 strings.HasPrefix(sub, ice.PS) {
if sub = kit.Select(sub, PP(key), sub == ice.PS); action.Hand == nil { 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) } 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 return nil, nil
}) })
} }
func ServeAction() ice.Actions { func ServeAction() ice.Actions {
return ice.Actions{ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { return gdb.EventsAction(SERVE_START, SERVE_REWRITE, SERVE_PARSE, SERVE_LOGIN, SERVE_CHECK, SERVE_RENDER, SERVE_STOP)
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)

View File

@ -19,8 +19,7 @@ import (
func _space_dial(m *ice.Message, dev, name string, arg ...string) { func _space_dial(m *ice.Message, dev, name string, arg ...string) {
msg := m.Cmd(SPIDE, dev) msg := m.Cmd(SPIDE, dev)
host := msg.Append(kit.Keys(tcp.CLIENT, tcp.HOSTNAME)) proto, host := strings.Replace(msg.Append(kit.Keys(tcp.CLIENT, tcp.PROTOCOL)), ice.HTTP, "ws", 1), 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)) 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() { m.Go(func() {
ls := strings.Split(host, ice.DF) 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 sleep := time.Duration(rand.Intn(a*(i+1))+b) * time.Millisecond
msg.Cost("order", i, "sleep", sleep, "reconnect", dev) msg.Cost("order", i, "sleep", sleep, "redial", dev)
if time.Sleep(sleep); mdb.HashSelect(msg).Length() == 0 { time.Sleep(sleep)
break
}
} }
}) })
} }

View File

@ -55,9 +55,9 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
func(key string, cmd *ice.Command) { func(key string, cmd *ice.Command) {
msg.Log(ROUTE, "%s <- %s", c.Name, key) msg.Log(ROUTE, "%s <- %s", c.Name, key)
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) { 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) }(key, cmd)
} }
}) })
@ -68,7 +68,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
cb(f) cb(f)
default: default:
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) { 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) defer mdb.HashModify(m, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP)
m.Warn(f.Server.Serve(l)) m.Warn(f.Server.Serve(l))
}) })

View File

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

View File

@ -81,6 +81,7 @@ func init() {
ctx.Run(m, arg...) ctx.Run(m, arg...)
}}, }},
}, mdb.HashAction(), ctx.CmdAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) { }, mdb.HashAction(), ctx.CmdAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) {
m.Debug(m.FormatChain())
if len(arg) > 0 && arg[0] == ctx.ACTION { if len(arg) > 0 && arg[0] == ctx.ACTION {
m.Option(mdb.TYPE, m.Cmd("", m.Option(mdb.HASH)).Append(mdb.TYPE)) m.Option(mdb.TYPE, m.Cmd("", m.Option(mdb.HASH)).Append(mdb.TYPE))
gdb.Event(m, FAVOR_ACTION, arg) 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, "没有登录") { if m.Warn(m.Option(ice.MSG_USERNAME) == "", ice.ErrNotLogin, "没有登录") {
return return
} }
if m.Warn(m.Option(web.SHARE) != "", ice.ErrNotRight, "没有权限") {
return
}
for i := 0; i < len(arg)-1; i += 2 { for i := 0; i < len(arg)-1; i += 2 {
m.Option(arg[i], arg[i+1]) 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))) arg = kit.Simple(os.Args[1:], kit.Split(kit.Env(CTX_ARG)))
} }
Pulse.meta[MSG_DETAIL] = 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) { switch Index.Merge(Index).Begin(Pulse, arg...); kit.Select("", arg, 0) {
case SERVE, SPACE: case SERVE, SPACE:
if Index.Start(Pulse, arg...) { if Index.Start(Pulse, arg...) {

10
logs.go
View File

@ -5,6 +5,7 @@ import (
"runtime" "runtime"
"strings" "strings"
"time" "time"
"unicode"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs" "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 { func (m *Message) Logs(level string, arg ...Any) *Message {
str, meta := m.join(arg...) str, meta := m.join(arg...)
if unicode.IsUpper([]rune(level)[0]) {
meta = []Any{logs.FileLineMeta("")}
}
return m.log(level, str, meta...) return m.log(level, str, meta...)
} }
@ -84,8 +88,9 @@ func (m *Message) Auth(arg ...Any) *Message {
} }
func (m *Message) Cost(arg ...Any) *Message { func (m *Message) Cost(arg ...Any) *Message {
str, meta := m.join(arg...) str, meta := m.join(arg...)
if len(arg) == 0 { if str == "" || len(arg) == 0 {
str = kit.Join(m.meta[MSG_DETAIL], SP) str = kit.Join(m.meta[MSG_DETAIL], SP)
meta = []Any{logs.FileLineMeta(m._fileline())}
} }
list := []string{m.FormatCost(), str} list := []string{m.FormatCost(), str}
return m.log(LOG_COST, kit.Join(list, SP), meta...) return m.log(LOG_COST, kit.Join(list, SP), meta...)
@ -187,11 +192,12 @@ func (m *Message) FormatChain() string {
meta := append([]string{}, NL) meta := append([]string{}, NL)
for i := len(ms) - 1; i >= 0; i-- { for i := len(ms) - 1; i >= 0; i-- {
msg := ms[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_DETAIL, len(msg.meta[MSG_DETAIL]), msg.meta[MSG_DETAIL],
MSG_OPTION, len(msg.meta[MSG_OPTION]), msg.meta[MSG_OPTION], MSG_OPTION, len(msg.meta[MSG_OPTION]), msg.meta[MSG_OPTION],
MSG_APPEND, len(msg.meta[MSG_APPEND]), msg.meta[MSG_APPEND], MSG_APPEND, len(msg.meta[MSG_APPEND]), msg.meta[MSG_APPEND],
MSG_RESULT, len(msg.meta[MSG_RESULT]), msg.meta[MSG_RESULT], MSG_RESULT, len(msg.meta[MSG_RESULT]), msg.meta[MSG_RESULT],
msg._cmd.GetFileLine(),
)) ))
for _, k := range msg.meta[MSG_OPTION] { for _, k := range msg.meta[MSG_OPTION] {
if v, ok := msg.meta[k]; ok { 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) return kit.Select("", m.meta[MSG_DETAIL], 0)
} }
func (m *Message) Detailv(arg ...Any) []string { func (m *Message) Detailv(arg ...Any) []string {
if len(arg) > 0 {
m.meta[MSG_DETAIL] = kit.Simple(arg...)
}
return m.meta[MSG_DETAIL] return m.meta[MSG_DETAIL]
} }
func (m *Message) Options(arg ...Any) Any { 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 { func (m *Message) _fileline() string {
switch m.target.Name { switch m.target.Name {
case MDB, AAA: case MDB, GDB, AAA:
return m._source return m._source
default: default:
return m._target 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 { func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
if m._key, m._cmd = key, cmd; cmd == nil { if m._key, m._cmd = key, cmd; cmd == nil {
return m 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 { 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)) m.Log(LOG_CMDS, "%s.%s %d %v %v", m.Target().Name, key, len(arg), arg, m.Optionv(MSG_FIELDS), logs.FileLineMeta(fileline))
} else { } 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) m.Cmdy(kit.Split(h.Name), arg)
return m 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 order := false
for i, v := range h.List { for i, v := range h.List {
name := kit.Format(kit.Value(v, NAME)) 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 order = true
} }
if order { if order {
m.Option(name, kit.Select(value, arg, i)) value = kit.Select(value, arg, i)
} else { }
m.OptionDefault(name, value) if value != "" {
m.Option(name, value)
} }
} }
if !order { if !order {
for i := 0; i < len(arg)-1; i += 2 { for i := 0; i < len(arg)-1; i += 2 {
if strings.HasPrefix(arg[i], PS) {
break
}
m.Option(arg[i], arg[i+1]) 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] { switch args := _tags_split(m.Option(PRE), m.Option(COL)); args[0] {
case "field": case "field":
m.Search(kit.Select(args[1], args, 2), func(key string, cmd *ice.Command) { 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]) m.Echo("vi +%s %s", ls[1], ls[0])
}) })
case "qrcode": 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) return kit.Keys(c.Cap(CTX_FOLLOW), arg)
} }
func (c *Command) GetFileLine() string { 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) { switch h := c.RawHand.(type) {
case string: case string:
return h return h
@ -348,11 +353,11 @@ func (m *Message) Spawn(arg ...Any) *Message {
json.Unmarshal(val, &msg.meta) json.Unmarshal(val, &msg.meta)
case Option: case Option:
msg.Option(val.Name, val.Value) msg.Option(val.Name, val.Value)
case Map: case Maps:
for k, v := range val { for k, v := range val {
msg.Option(k, v) msg.Option(k, v)
} }
case Maps: case Map:
for k, v := range val { for k, v := range val {
msg.Option(k, v) msg.Option(k, v)
} }
@ -362,6 +367,8 @@ func (m *Message) Spawn(arg ...Any) *Message {
msg.R = val msg.R = val
case *Context: case *Context:
msg.target = val msg.target = val
case *Command:
msg._cmd = val
case string: case string:
msg._key = val msg._key = val
} }