forked from x/ContextOS
vpn del other 0.1分支只维护ctx和cli模块
This commit is contained in:
parent
a454b662fc
commit
47c81a79fd
18
etc/cert.pem
18
etc/cert.pem
@ -1,18 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIC9TCCAl4CCQCHSqshz+HyLTANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC
|
|
||||||
R0IxHzAdBgNVBAgTFlRlc3QgU3RhdGUgb3IgUHJvdmluY2UxFjAUBgNVBAcTDVRl
|
|
||||||
c3QgTG9jYWxpdHkxGjAYBgNVBAoTEU9yZ2FuaXphdGlvbiBOYW1lMSEwHwYDVQQL
|
|
||||||
ExhPcmdhbml6YXRpb25hbCBVbml0IE5hbWUxFDASBgNVBAMTC0NvbW1vbiBOYW1l
|
|
||||||
MSEwHwYJKoZIhvcNAQkBFhJ0ZXN0QGVtYWlsLmFkZHJlc3MwHhcNMTcxMDMxMTYw
|
|
||||||
NDM5WhcNMTcxMTMwMTYwNDM5WjCBvjELMAkGA1UEBhMCR0IxHzAdBgNVBAgTFlRl
|
|
||||||
c3QgU3RhdGUgb3IgUHJvdmluY2UxFjAUBgNVBAcTDVRlc3QgTG9jYWxpdHkxGjAY
|
|
||||||
BgNVBAoTEU9yZ2FuaXphdGlvbiBOYW1lMSEwHwYDVQQLExhPcmdhbml6YXRpb25h
|
|
||||||
bCBVbml0IE5hbWUxFDASBgNVBAMTC0NvbW1vbiBOYW1lMSEwHwYJKoZIhvcNAQkB
|
|
||||||
FhJ0ZXN0QGVtYWlsLmFkZHJlc3MwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
|
|
||||||
AOw3gvdtfKWkSEl2l30V7irBhkrD6IVd6AzxaAYL97giDglPvu7ng2PXYlF5pjjf
|
|
||||||
mxDYtjAGuq1itnN0LKRe6CjUOuGtC2KMlZ8121fQCNw8M6TLPSpDjVuzysaUb2ds
|
|
||||||
+OClb0uC8SmSy3bOCGsicI77yXvEuKFkm43ikyVounmRAgMBAAEwDQYJKoZIhvcN
|
|
||||||
AQELBQADgYEAkOk7DVR/XgJdMSXXGd/OtWmTfVp2sIyyy37zSoc4uRFWwPqbzLPf
|
|
||||||
NgUKGNHEYvJY7/bWQ3p2D+u1U2PUfv/t6SQcAu3Nkw7sd7PoeeDZcRau84NevgoR
|
|
||||||
HfQKirJQgZd0hKFwiBnDspYbi8IL2mHEJOlzw1priY9v8MVIscyFVbE=
|
|
||||||
-----END CERTIFICATE-----
|
|
@ -1,9 +0,0 @@
|
|||||||
alias ~ context
|
|
||||||
alias ! history
|
|
||||||
alias @ config
|
|
||||||
alias $ cache
|
|
||||||
alias & server
|
|
||||||
alias * message
|
|
||||||
|
|
||||||
~ssh
|
|
||||||
&
|
|
15
etc/key.pem
15
etc/key.pem
@ -1,15 +0,0 @@
|
|||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIICXwIBAAKBgQDsN4L3bXylpEhJdpd9Fe4qwYZKw+iFXegM8WgGC/e4Ig4JT77u
|
|
||||||
54Nj12JReaY435sQ2LYwBrqtYrZzdCykXugo1DrhrQtijJWfNdtX0AjcPDOkyz0q
|
|
||||||
Q41bs8rGlG9nbPjgpW9LgvEpkst2zghrInCO+8l7xLihZJuN4pMlaLp5kQIDAQAB
|
|
||||||
AoGBAOasYwG68pFTN6A95jupsdYg/EKAw82RYa1aBUp6X2N6JhjjvkHQ5ZcXWxTT
|
|
||||||
ZgZ+HhC6gFewCpaNIjzmwz2UzMJJ4empijEbJFuwZCq4M/Adca2BhduV2YIwqvi8
|
|
||||||
MHGmHMB81zYKA0E4j+vahJnn8aAqSoPnaM9MBw5vhggU5YodAkEA/IwRTVNOHmIm
|
|
||||||
1XCfvPoSpDBpSJh6V1mPyBuPs/2Fr52j+L+6qOhNML0O063az44/dR8RZytcaGYQ
|
|
||||||
7EByYbeCZwJBAO9ySW4TbDLRejSmFWHmflrnjV7s4DqE6OBbCRJF3aIleELYaTPC
|
|
||||||
Q0kOKRZTCr1PwopIdAOOOgaSWgsX75zU2UcCQQDMCwb3qLTXC4pArMwCzTE+gvat
|
|
||||||
drRx2qS2kr4aOF1ItF8E3TOcwIONO1K9aBv/0fgnUsCm0HvKxZwqpS9FEBVFAkEA
|
|
||||||
ntgeRlu0J3I3s72J6cxSflOlwRc7GRcatdsuhWS7xtk8knumLqPspwYx05F7SmMj
|
|
||||||
F0FBVSqA6+MiwME8P7oj+QJBAJFv2HKAaGElXkaJJzmQPHGJdGLUMb9oHXPtzcpz
|
|
||||||
HLtT2kHK1LlQqsOEacivPCKtnnLkX6Xsl8pMpe8EV43t718=
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
@ -1,105 +0,0 @@
|
|||||||
package aaa // {{{
|
|
||||||
// }}}
|
|
||||||
import ( // {{{
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
type AAA struct {
|
|
||||||
username string
|
|
||||||
password string
|
|
||||||
logintime time.Time
|
|
||||||
*ctx.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (aaa *AAA) Begin(m *ctx.Message) ctx.Server { // {{{
|
|
||||||
return aaa
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (aaa *AAA) Start(m *ctx.Message) bool { // {{{
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (aaa *AAA) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|
||||||
c.Caches = map[string]*ctx.Cache{}
|
|
||||||
c.Configs = map[string]*ctx.Config{}
|
|
||||||
c.Commands = map[string]*ctx.Command{}
|
|
||||||
|
|
||||||
s := new(AAA)
|
|
||||||
s.username = arg[0]
|
|
||||||
s.password = arg[1]
|
|
||||||
s.logintime = time.Now()
|
|
||||||
s.Context = c
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (aaa *AAA) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
var Index = &ctx.Context{Name: "aaa", Help: "会话管理",
|
|
||||||
Caches: map[string]*ctx.Cache{
|
|
||||||
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
|
|
||||||
"root": &ctx.Cache{Name: "root", Value: "root", Help: "初始用户"},
|
|
||||||
},
|
|
||||||
Configs: map[string]*ctx.Config{},
|
|
||||||
Commands: map[string]*ctx.Command{
|
|
||||||
"login": &ctx.Command{Name: "login [username [password]]", Help: "会话管理", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
|
||||||
m.Target.Travel(func(s *ctx.Context) bool {
|
|
||||||
aaa := s.Server.(*AAA)
|
|
||||||
m.Echo("%s(%s): %s\n", s.Name, aaa.username, aaa.logintime.Format("15:04:05"))
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
case 1:
|
|
||||||
m.Target.Travel(func(s *ctx.Context) bool {
|
|
||||||
aaa := s.Server.(*AAA)
|
|
||||||
if aaa.username == arg[0] {
|
|
||||||
m.Echo("%s(%s): %s\n", s.Name, aaa.username, aaa.logintime.Format("15:04:05"))
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
case 2:
|
|
||||||
m.Target.Travel(func(s *ctx.Context) bool {
|
|
||||||
aaa := s.Server.(*AAA)
|
|
||||||
if aaa.username == arg[0] {
|
|
||||||
m.Add("result", arg[0])
|
|
||||||
if aaa.password == arg[1] {
|
|
||||||
m.Add("result", time.Now().Format("15:04:05"))
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if m.Get("result") == arg[0] {
|
|
||||||
if len(m.Meta["result"]) == 2 {
|
|
||||||
m.Echo("login success\n")
|
|
||||||
log.Println("login success")
|
|
||||||
} else {
|
|
||||||
m.Echo("login error\n")
|
|
||||||
log.Println("login error")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.Start(arg[0], arg[1])
|
|
||||||
m.Add("result", arg[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
aaa := &AAA{username: "root", password: "root", logintime: time.Now()}
|
|
||||||
aaa.Context = Index
|
|
||||||
ctx.Index.Register(Index, aaa)
|
|
||||||
}
|
|
@ -56,7 +56,7 @@ func (cli *CLI) parse(m *ctx.Message) bool { // {{{
|
|||||||
if e == io.EOF {
|
if e == io.EOF {
|
||||||
l := len(cli.ins)
|
l := len(cli.ins)
|
||||||
if l == 1 {
|
if l == 1 {
|
||||||
cli.echo("\n%s\n", cli.Conf("结束语"))
|
// cli.echo("\n%s\n", cli.Conf("结束语"))
|
||||||
return false
|
return false
|
||||||
ls = "exit"
|
ls = "exit"
|
||||||
e = nil
|
e = nil
|
||||||
@ -167,7 +167,10 @@ func (cli *CLI) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|||||||
|
|
||||||
cli.target = cli.Context
|
cli.target = cli.Context
|
||||||
|
|
||||||
cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量"}
|
cli.Caches["nhistory"] = &ctx.Cache{Name: "历史命令数量", Value: "0", Help: "当前终端已经执行命令的数量", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string {
|
||||||
|
x.Value = fmt.Sprintf("%d", len(cli.history))
|
||||||
|
return x.Value
|
||||||
|
}}
|
||||||
|
|
||||||
return cli
|
return cli
|
||||||
}
|
}
|
||||||
@ -193,7 +196,7 @@ func (cli *CLI) Start(m *ctx.Message, arg ...string) bool { // {{{
|
|||||||
cli.push(f)
|
cli.push(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.echo("%s\n", cli.Conf("hello"))
|
// cli.echo("%s\n", cli.Conf("hello"))
|
||||||
|
|
||||||
go cli.AssertOne(m, true, func(c *ctx.Context, m *ctx.Message) {
|
go cli.AssertOne(m, true, func(c *ctx.Context, m *ctx.Message) {
|
||||||
for cli.parse(m) {
|
for cli.parse(m) {
|
||||||
@ -255,8 +258,8 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
},
|
},
|
||||||
Configs: map[string]*ctx.Config{
|
Configs: map[string]*ctx.Config{
|
||||||
"slient": &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"},
|
"slient": &ctx.Config{Name: "屏蔽脚本输出(yes/no)", Value: "yes", Help: "屏蔽脚本输出的信息,yes:屏蔽,no:不屏蔽"},
|
||||||
"hello": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "模块启动时输出的信息"},
|
// "hello": &ctx.Config{Name: "开场白", Value: "\n~~~ Hello Context & Message World ~~~\n", Help: "模块启动时输出的信息"},
|
||||||
"byebye": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "模块停止时输出的信息"},
|
// "byebye": &ctx.Config{Name: "结束语", Value: "\n~~~ Byebye Context & Message World ~~~\n", Help: "模块停止时输出的信息"},
|
||||||
|
|
||||||
"PS1": &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string {
|
"PS1": &ctx.Config{Name: "命令行提示符(target/detail)", Value: "target", Help: "命令行提示符,target:显示当前模块,detail:显示详细信息", Hand: func(c *ctx.Context, x *ctx.Config, arg ...string) string {
|
||||||
cli, ok := c.Server.(*CLI) // {{{
|
cli, ok := c.Server.(*CLI) // {{{
|
||||||
@ -276,89 +279,90 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ctx.Command{
|
Commands: map[string]*ctx.Command{
|
||||||
"context": &ctx.Command{Name: "context [spawn|find|search name [which]]|root|back|home", Help: "查看上下文", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"context": &ctx.Command{Name: "context [root|back|home] [[find|search] name] [show|spawn|start|switch][args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块,args:启动参数", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
cli, ok := c.Server.(*CLI) // {{{
|
cli, ok := c.Server.(*CLI) // {{{
|
||||||
switch len(arg) {
|
if !ok {
|
||||||
case 0:
|
return ""
|
||||||
// cs := []*ctx.Context{m.Target}
|
|
||||||
cs := []*ctx.Context{m.Target.Root}
|
|
||||||
for i := 0; i < len(cs); i++ {
|
|
||||||
if len(cs[i].Contexts) > 0 {
|
|
||||||
m.Echo("%s: ", cs[i].Name)
|
|
||||||
for k, v := range cs[i].Contexts {
|
|
||||||
cs = append(cs, v)
|
|
||||||
m.Echo("%s, ", k)
|
|
||||||
}
|
|
||||||
m.Echo("\n")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
switch arg[0] {
|
|
||||||
case "root":
|
|
||||||
if ok {
|
|
||||||
cli.target = cli.Context.Root
|
|
||||||
} else {
|
|
||||||
m.Target = m.Target.Root
|
|
||||||
}
|
|
||||||
case "back":
|
|
||||||
if ok {
|
|
||||||
if cli.Context.Context != nil {
|
|
||||||
cli.target = cli.Context.Context
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if m.Target.Context != nil {
|
|
||||||
m.Target = m.Target.Context
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "home":
|
|
||||||
if ok {
|
|
||||||
cli.target = cli.Context
|
|
||||||
} else {
|
|
||||||
m.Target = m.Context
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// if cs := m.Target.Find(strings.Split(arg[1], ".")); cs != nil {
|
|
||||||
if cs := c.Root.Search(arg[0]); cs != nil && len(cs) > 0 {
|
|
||||||
if ok {
|
|
||||||
cli.target = cs[0]
|
|
||||||
} else {
|
|
||||||
m.Target = cs[0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 2, 3:
|
|
||||||
switch arg[0] {
|
|
||||||
case "spawn":
|
|
||||||
m.Target.Spawn(m, arg[1])
|
|
||||||
case "find":
|
|
||||||
cs := m.Target.Find(arg[1])
|
|
||||||
if cs != nil {
|
|
||||||
m.Echo("%s: %s\n", cs.Name, cs.Help)
|
|
||||||
if len(arg) == 4 {
|
|
||||||
if ok {
|
|
||||||
cli.target = cs
|
|
||||||
} else {
|
|
||||||
m.Target = cs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case "search":
|
|
||||||
cs := m.Target.Search(arg[1])
|
|
||||||
for i, v := range cs {
|
|
||||||
m.Echo("[%d] %s: %s\n", i, v.Name, v.Help)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(arg) == 3 {
|
switch len(arg) {
|
||||||
n, e := strconv.Atoi(arg[2])
|
case 0:
|
||||||
if 0 <= n && n < len(cs) && e == nil {
|
m.Target.Root.Travel(func(c *ctx.Context) bool {
|
||||||
if ok {
|
if c.Context != nil {
|
||||||
cli.target = cs[n]
|
m.Echo("%s: %s(%s)\n", c.Context.Name, c.Name, c.Help)
|
||||||
} else {
|
|
||||||
m.Target = cs[n]
|
|
||||||
}
|
}
|
||||||
} else {
|
return true
|
||||||
m.Echo("参数错误(0<=n<%s)", len(cs))
|
})
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target := m.Target.Root
|
||||||
|
method := "search"
|
||||||
|
action := "switch"
|
||||||
|
which := ""
|
||||||
|
args := []string{}
|
||||||
|
|
||||||
|
for len(arg) > 0 {
|
||||||
|
switch arg[0] {
|
||||||
|
case "root":
|
||||||
|
target = m.Target.Root
|
||||||
|
case "back":
|
||||||
|
if m.Target.Context != nil {
|
||||||
|
target = m.Target.Context
|
||||||
|
}
|
||||||
|
case "home":
|
||||||
|
target = m.Target
|
||||||
|
case "find", "search":
|
||||||
|
method = arg[0]
|
||||||
|
which = arg[1]
|
||||||
|
arg = arg[1:]
|
||||||
|
case "switch", "spawn", "start", "show":
|
||||||
|
action = arg[0]
|
||||||
|
args = arg[1:]
|
||||||
|
arg = arg[:1]
|
||||||
|
default:
|
||||||
|
which = arg[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
arg = arg[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
cs := []*ctx.Context{}
|
||||||
|
|
||||||
|
if which == "" {
|
||||||
|
cs = append(cs, target)
|
||||||
|
} else {
|
||||||
|
switch method {
|
||||||
|
case "search":
|
||||||
|
if s := target.Search(which); len(s) > 0 {
|
||||||
|
cs = append(cs, s...)
|
||||||
|
}
|
||||||
|
case "find":
|
||||||
|
if s := target.Find(which); s != nil {
|
||||||
|
cs = append(cs, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range cs {
|
||||||
|
switch action {
|
||||||
|
case "switch":
|
||||||
|
cli.target = v
|
||||||
|
case "spawn":
|
||||||
|
msg := m.Spawn(v)
|
||||||
|
v.Spawn(msg, args[0], args[1:]...)
|
||||||
|
v.Begin(msg)
|
||||||
|
case "start":
|
||||||
|
m.Spawn(v).Start(args...)
|
||||||
|
case "show":
|
||||||
|
m.Echo("%s: %s\n", v.Name, v.Help)
|
||||||
|
m.Echo("引用模块:\n")
|
||||||
|
for k, v := range v.Session {
|
||||||
|
m.Echo("\t%s(%d): %s %s\n", k, v.Code, v.Target.Name, v.Target.Help)
|
||||||
|
}
|
||||||
|
m.Echo("索引模块:\n")
|
||||||
|
for i, v := range v.Resource {
|
||||||
|
m.Echo("\t%d(%d): %s %s\n", i, v.Code, v.Context.Name, v.Context.Help)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,12 +370,10 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"message": &ctx.Command{Name: "message detail...", Help: "查看上下文", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"message": &ctx.Command{Name: "message", Help: "查看上下文", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
// {{{
|
ms := []*ctx.Message{ctx.Pulse} // {{{
|
||||||
ms := []*ctx.Message{ctx.Pulse}
|
|
||||||
for i := 0; i < len(ms); i++ {
|
for i := 0; i < len(ms); i++ {
|
||||||
m.Echo("%d %s.%s -> %s.%d\n", ms[i].Code, ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index)
|
m.Echo("%d %s.%s -> %s.%d: %s %v\n", ms[i].Code, ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index, ms[i].Time.Format("15:04:05"), ms[i].Meta["detail"])
|
||||||
// m.Echo("%d %s %s.%s -> %s.%d\n", ms[i].Code, ms[i].Time.Format("2006/01/02 15:03:04"), ms[i].Context.Name, ms[i].Name, ms[i].Target.Name, ms[i].Index)
|
|
||||||
ms = append(ms, ms[i].Messages...)
|
ms = append(ms, ms[i].Messages...)
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
@ -381,17 +383,13 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
s := m.Target // {{{
|
s := m.Target // {{{
|
||||||
switch len(arg) {
|
switch len(arg) {
|
||||||
case 0:
|
case 0:
|
||||||
cs := []*ctx.Context{m.Target.Root}
|
m.Target.Root.Travel(func(c *ctx.Context) bool {
|
||||||
for i := 0; i < len(cs); i++ {
|
if x, ok := c.Caches["status"]; ok {
|
||||||
if x, ok := cs[i].Caches["status"]; ok {
|
m.Echo("%s(%s): %s\n", c.Name, x.Value, c.Help)
|
||||||
m.Echo("%s(%s): %s\n", cs[i].Name, x.Value, cs[i].Help)
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
for _, v := range cs[i].Contexts {
|
|
||||||
cs = append(cs, v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "server start"
|
|
||||||
case 1:
|
case 1:
|
||||||
switch arg[0] {
|
switch arg[0] {
|
||||||
case "start":
|
case "start":
|
||||||
@ -460,80 +458,112 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"command": &ctx.Command{Name: "command [name [value [help]]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"command": &ctx.Command{Name: "command [all] [name args]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
switch len(arg) { // {{{
|
all := false // {{{
|
||||||
case 0:
|
if len(arg) > 0 && arg[0] == "all" {
|
||||||
for k, v := range m.Target.Commands {
|
arg = arg[1:]
|
||||||
m.Echo("%s: %s\n", k, v.Help)
|
all = true
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
if v, ok := m.Target.Commands[arg[0]]; ok {
|
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
|
||||||
}
|
|
||||||
case 3:
|
|
||||||
switch arg[0] {
|
|
||||||
case "delete":
|
|
||||||
if _, ok := m.Target.Commands[arg[1]]; ok {
|
|
||||||
delete(m.Target.Commands, arg[1])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Echo("\n")
|
m.Target.BackTrace(func(s *ctx.Context) bool {
|
||||||
|
switch len(arg) {
|
||||||
|
case 0:
|
||||||
|
for k, v := range s.Commands {
|
||||||
|
m.Echo("%s: %s\n", k, v.Name)
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if v, ok := s.Commands[arg[0]]; ok {
|
||||||
|
m.Echo("%s\n%s\n", v.Name, v.Help)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
m.Spawn(s).Cmd(arg...)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return all
|
||||||
|
})
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"config": &ctx.Command{Name: "config [name [value [help]]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"config": &ctx.Command{Name: "config [all] [key value|[name value help]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
switch len(arg) { // {{{
|
all := false // {{{
|
||||||
|
if len(arg) > 0 && arg[0] == "all" {
|
||||||
|
arg = arg[1:]
|
||||||
|
all = true
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Target.BackTrace(func(s *ctx.Context) bool {
|
||||||
|
switch len(arg) {
|
||||||
case 0:
|
case 0:
|
||||||
for k, v := range m.Target.Configs {
|
for k, v := range s.Configs {
|
||||||
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
if v, ok := m.Target.Configs[arg[0]]; ok {
|
if v, ok := s.Configs[arg[0]]; ok {
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
m.Echo("%s: %s\n", v.Name, v.Help)
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
|
if s != m.Target {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
switch arg[0] {
|
switch arg[0] {
|
||||||
case "void":
|
case "void":
|
||||||
m.Target.Conf(arg[1], "")
|
s.Conf(arg[1], "")
|
||||||
case "delete":
|
case "delete":
|
||||||
if _, ok := m.Target.Configs[arg[1]]; ok {
|
if _, ok := s.Configs[arg[1]]; ok {
|
||||||
delete(m.Target.Configs, arg[1])
|
delete(s.Configs, arg[1])
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
m.Target.Conf(arg[0], arg[1])
|
s.Conf(arg[0], arg[1])
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
m.Target.Conf(arg[0], arg[1:]...)
|
s.Conf(arg[0], arg[1:]...)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return all
|
||||||
|
})
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"cache": &ctx.Command{Name: "cache [name [value [help]]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
"cache": &ctx.Command{Name: "cache [all] [key value|[name value help]]", Help: "查看修改添加配置", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
switch len(arg) { // {{{
|
all := false // {{{
|
||||||
|
if len(arg) > 0 && arg[0] == "all" {
|
||||||
|
arg = arg[1:]
|
||||||
|
all = true
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Target.BackTrace(func(s *ctx.Context) bool {
|
||||||
|
switch len(arg) {
|
||||||
case 0:
|
case 0:
|
||||||
for k, v := range m.Target.Caches {
|
for k, v := range s.Caches {
|
||||||
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
m.Echo("%s(%s): %s\n", k, v.Value, v.Name)
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
if v, ok := m.Target.Caches[arg[0]]; ok {
|
if v, ok := s.Caches[arg[0]]; ok {
|
||||||
m.Echo("%s: %s\n", v.Name, v.Help)
|
m.Echo("%s: %s\n", v.Name, v.Help)
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
|
if s != m.Target {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
switch arg[0] {
|
switch arg[0] {
|
||||||
case "delete":
|
case "delete":
|
||||||
if _, ok := m.Target.Caches[arg[1]]; ok {
|
if _, ok := s.Caches[arg[1]]; ok {
|
||||||
delete(m.Target.Caches, arg[1])
|
delete(s.Caches, arg[1])
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if _, ok := m.Target.Caches[arg[0]]; ok {
|
if _, ok := s.Caches[arg[0]]; ok {
|
||||||
m.Echo("%s: %s\n", arg[0], m.Target.Cap(arg[0], arg[1:]...))
|
m.Echo("%s: %s\n", arg[0], s.Cap(arg[0], arg[1:]...))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
m.Target.Cap(arg[0], arg[1:]...)
|
s.Cap(arg[0], arg[1:]...)
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return all
|
||||||
|
})
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
@ -572,10 +602,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理终端",
|
|||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
"accept": &ctx.Command{Name: "accept address protocl", Help: "建立远程连接",
|
"open": &ctx.Command{Name: "open address protocl", Help: "建立远程连接",
|
||||||
Options: map[string]string{"io": "读写流"},
|
Options: map[string]string{"io": "读写流"},
|
||||||
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
||||||
m.Start(fmt.Sprintf("PTS%d", c.Capi("nterm")), arg[1]) // {{{
|
if m.Has("io") {
|
||||||
|
m.Start(fmt.Sprintf("PTS%d", c.Capi("nterm")), arg[1])
|
||||||
|
} else {
|
||||||
|
switch arg[1] {
|
||||||
|
case "tcp":
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// {{{
|
||||||
return ""
|
return ""
|
||||||
// }}}
|
// }}}
|
||||||
}},
|
}},
|
||||||
|
@ -327,9 +327,9 @@ func (c *Context) Register(s *Context, x Server) *Context { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Begin(m *Message) *Context { // {{{
|
func (c *Context) Begin(m *Message) *Context { // {{{
|
||||||
for _, x := range c.Configs {
|
for k, x := range c.Configs {
|
||||||
if x.Hand != nil {
|
if x.Hand != nil {
|
||||||
log.Println(c.Name, "conf:", x.Name, x.Value)
|
log.Printf("%s conf: %s(%s)", c.Name, k, x.Value)
|
||||||
x.Hand(c, x, x.Value)
|
x.Hand(c, x, x.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -347,7 +347,7 @@ func (c *Context) Begin(m *Message) *Context { // {{{
|
|||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Start(m *Message) bool { // {{{
|
func (c *Context) Start(m *Message) bool { // {{{
|
||||||
if _, ok := c.Caches["status"]; !ok {
|
if _, ok := c.Caches["status"]; !ok {
|
||||||
c.Caches["status"] = &Cache{Name: "status", Value: "stop", Help: "服务状态"}
|
c.Caches["status"] = &Cache{Name: "服务状态", Value: "stop", Help: "服务状态,start:正在运行,stop:未在运行"}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.Cap("status") != "start" && c.Server != nil {
|
if c.Cap("status") != "start" && c.Server != nil {
|
||||||
@ -634,6 +634,15 @@ func (c *Context) Travel(hand func(s *Context) bool) { // {{{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// }}}
|
||||||
|
func (c *Context) BackTrace(hand func(s *Context) bool) { // {{{
|
||||||
|
for cs := c; cs != nil; cs = cs.Context {
|
||||||
|
if !hand(cs) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
func (c *Context) Search(name string) []*Context { // {{{
|
func (c *Context) Search(name string) []*Context { // {{{
|
||||||
cs := make([]*Context, 0, 3)
|
cs := make([]*Context, 0, 3)
|
||||||
@ -723,7 +732,7 @@ func (c *Context) Conf(key string, arg ...string) string { // {{{
|
|||||||
case 3:
|
case 3:
|
||||||
log.Println(c.Name, "conf:", key, arg)
|
log.Println(c.Name, "conf:", key, arg)
|
||||||
if s == c {
|
if s == c {
|
||||||
panic(errors.New(x.Name + "配置项已存在"))
|
panic(errors.New(key + "配置项已存在"))
|
||||||
}
|
}
|
||||||
if c.Configs == nil {
|
if c.Configs == nil {
|
||||||
c.Configs = make(map[string]*Config)
|
c.Configs = make(map[string]*Config)
|
||||||
@ -818,7 +827,7 @@ func (c *Context) Capi(key string, arg ...int) int { // {{{
|
|||||||
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
var Pulse = &Message{Code: 0, Time: time.Now(), Index: 0, Name: "root"}
|
var Pulse = &Message{Code: 1, Time: time.Now(), Index: 0, Name: "root"}
|
||||||
|
|
||||||
var Index = &Context{Name: "ctx", Help: "所有模块的祖模块",
|
var Index = &Context{Name: "ctx", Help: "所有模块的祖模块",
|
||||||
Caches: map[string]*Cache{
|
Caches: map[string]*Cache{
|
||||||
|
@ -1,254 +0,0 @@
|
|||||||
package ssh // {{{
|
|
||||||
// }}}
|
|
||||||
import ( // {{{
|
|
||||||
"bufio"
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
type SSH struct {
|
|
||||||
w io.WriteCloser
|
|
||||||
bio *bufio.Reader
|
|
||||||
|
|
||||||
meta map[string][]string
|
|
||||||
data []byte
|
|
||||||
head map[string][]string
|
|
||||||
body []string
|
|
||||||
len int
|
|
||||||
|
|
||||||
*ctx.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ssh *SSH) Scan() bool { // {{{
|
|
||||||
if ssh.meta != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
meta := make(map[string][]string)
|
|
||||||
|
|
||||||
for {
|
|
||||||
l, e := ssh.bio.ReadString('\n')
|
|
||||||
ssh.Check(e)
|
|
||||||
|
|
||||||
log.Printf("%s >> %s", ssh.Name, l)
|
|
||||||
if len(l) == 1 {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
ls := strings.SplitN(l, ":", 2)
|
|
||||||
ls[0] = strings.TrimSpace(ls[0])
|
|
||||||
ls[1] = strings.TrimSpace(ls[1])
|
|
||||||
|
|
||||||
if m, ok := meta[ls[0]]; ok {
|
|
||||||
meta[ls[0]] = append(m, ls[1])
|
|
||||||
} else {
|
|
||||||
meta[ls[0]] = []string{ls[1]}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh.meta = meta
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) Has(field string) bool { // {{{
|
|
||||||
_, ok := ssh.meta[field]
|
|
||||||
return ok
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) Get(field string) string { // {{{
|
|
||||||
if m, ok := ssh.meta[field]; ok {
|
|
||||||
return m[0]
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
func (ssh *SSH) Echo(name string, value interface{}) { // {{{
|
|
||||||
fmt.Fprintln(ssh.w, name+":", value)
|
|
||||||
log.Println(ssh.Name, "<<", name+":", value)
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) Print(str string, arg ...interface{}) { // {{{
|
|
||||||
if ssh.body == nil {
|
|
||||||
ssh.body = make([]string, 0, 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
s := fmt.Sprintf(str, arg...)
|
|
||||||
ssh.body = append(ssh.body, s)
|
|
||||||
ssh.len += len(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) End() { // {{{
|
|
||||||
ssh.Echo("len", ssh.len)
|
|
||||||
fmt.Fprintln(ssh.w)
|
|
||||||
log.Println(ssh.Name, "<<")
|
|
||||||
|
|
||||||
if ssh.len > 0 {
|
|
||||||
for i, v := range ssh.body {
|
|
||||||
n, e := fmt.Fprintf(ssh.w, v)
|
|
||||||
log.Println(ssh.Name, "<<", i, n, v)
|
|
||||||
ssh.Check(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ssh.Check(ssh.w.Flush())
|
|
||||||
log.Println("\n")
|
|
||||||
|
|
||||||
ssh.meta = nil
|
|
||||||
ssh.body = nil
|
|
||||||
ssh.len = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
func (ssh *SSH) Begin() bool { // {{{
|
|
||||||
// ssh.Conf("log", ssh.Conf("log"))
|
|
||||||
for k, v := range ssh.Configs {
|
|
||||||
ssh.Conf(k, v.Value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) Start() bool { // {{{
|
|
||||||
ssh.Begin()
|
|
||||||
|
|
||||||
if ssh.Cap("status") == "start" {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
defer ssh.Cap("status", "stop")
|
|
||||||
|
|
||||||
if ssh.Conf("client") == "yes" {
|
|
||||||
conn, e := tls.Dial("tcp", ssh.Conf("address"), &tls.Config{InsecureSkipVerify: true})
|
|
||||||
ssh.Check(e)
|
|
||||||
ssh.w = conn
|
|
||||||
ssh.bio = bufio.NewReader(conn)
|
|
||||||
log.Println(ssh.Name, "->", conn.RemoteAddr(), "connect")
|
|
||||||
ssh.Cap("status", "start")
|
|
||||||
|
|
||||||
ssh.Echo("master", ssh.Conf("master"))
|
|
||||||
ssh.End()
|
|
||||||
|
|
||||||
ssh.Scan()
|
|
||||||
if ssh.Get("master") == "yes" {
|
|
||||||
ssh.Conf("master", "no")
|
|
||||||
} else {
|
|
||||||
ssh.Conf("master", "yes")
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("fuck")
|
|
||||||
ssh.End()
|
|
||||||
|
|
||||||
if ssh.Conf("master") == "yes" {
|
|
||||||
} else {
|
|
||||||
for ssh.Scan() {
|
|
||||||
m := &ctx.Message{Meta: ssh.meta}
|
|
||||||
m.Context = ssh.Context
|
|
||||||
ssh.Root.Find([]string{"cli"}).Post(m)
|
|
||||||
ssh.End()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
pair, e := tls.LoadX509KeyPair(ssh.Conf("cert"), ssh.Conf("key"))
|
|
||||||
ssh.Check(e)
|
|
||||||
|
|
||||||
ls, e := tls.Listen("tcp", ssh.Conf("address"), &tls.Config{Certificates: []tls.Certificate{pair}})
|
|
||||||
ssh.Check(e)
|
|
||||||
ssh.Cap("status", "start")
|
|
||||||
for {
|
|
||||||
conn, e := ls.Accept()
|
|
||||||
ssh.Check(e)
|
|
||||||
log.Println(ssh.Name, "<-", conn.RemoteAddr(), "connect")
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
s := ssh.Context.Spawn(conn.RemoteAddr().String())
|
|
||||||
psh := s.Server.(*SSH)
|
|
||||||
psh.w = conn
|
|
||||||
psh.bio = bufio.NewReader(conn)
|
|
||||||
|
|
||||||
psh.Scan()
|
|
||||||
if psh.Get("master") == "yes" {
|
|
||||||
psh.Conf("master", "master", "no", "主控或被控")
|
|
||||||
} else {
|
|
||||||
psh.Conf("master", "master", "yes", "主控或被控")
|
|
||||||
}
|
|
||||||
|
|
||||||
psh.Echo("master", psh.Conf("master"))
|
|
||||||
psh.End()
|
|
||||||
|
|
||||||
psh.Scan()
|
|
||||||
|
|
||||||
if psh.Conf("master") == "yes" {
|
|
||||||
} else {
|
|
||||||
psh.meta = nil
|
|
||||||
for psh.Scan() {
|
|
||||||
m := &ctx.Message{Meta: psh.meta, Wait: make(chan bool)}
|
|
||||||
psh.Root.Find([]string{"cli"}).Post(m)
|
|
||||||
for _, v := range m.Meta["result"] {
|
|
||||||
psh.Echo("result", v)
|
|
||||||
}
|
|
||||||
|
|
||||||
psh.End()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (ssh *SSH) Spawn(c *ctx.Context, arg ...string) ctx.Server { // {{{
|
|
||||||
s := new(SSH)
|
|
||||||
s.Context = c
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "ssh", Help: "远程控制",
|
|
||||||
Caches: map[string]*ctx.Cache{},
|
|
||||||
Configs: map[string]*ctx.Config{
|
|
||||||
"master": &ctx.Config{Name: "master", Value: "yes", Help: "主控或被控"},
|
|
||||||
"client": &ctx.Config{Name: "client", Value: "yes", Help: "连接或监听"},
|
|
||||||
"address": &ctx.Config{Name: "address", Value: ":9090", Help: "连接或监听的地址"},
|
|
||||||
},
|
|
||||||
Commands: map[string]*ctx.Command{
|
|
||||||
"remote": &ctx.Command{"remote", "远程命令", func(c *ctx.Context, msg *ctx.Message, arg ...string) string {
|
|
||||||
ssh := c.Server.(*SSH) // {{{
|
|
||||||
if c.Conf("master") == "yes" {
|
|
||||||
for _, v := range arg[1:] {
|
|
||||||
ssh.Echo("detail", v)
|
|
||||||
}
|
|
||||||
ssh.End()
|
|
||||||
}
|
|
||||||
ssh.Scan()
|
|
||||||
for _, v := range ssh.meta["result"] {
|
|
||||||
msg.Echo(v)
|
|
||||||
}
|
|
||||||
msg.Echo("\n")
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
ssh := &SSH{}
|
|
||||||
ssh.Context = Index
|
|
||||||
ctx.Index.Register(Index, ssh)
|
|
||||||
}
|
|
@ -1,138 +0,0 @@
|
|||||||
package tcp
|
|
||||||
|
|
||||||
import ( // {{{
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
type TCP struct {
|
|
||||||
listener net.Listener
|
|
||||||
*ctx.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tcp *TCP) Begin(m *ctx.Message) ctx.Server { // {{{
|
|
||||||
return tcp
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (tcp *TCP) Start(m *ctx.Message) bool { // {{{
|
|
||||||
if tcp.Conf("address") == "" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
l, e := net.Listen("tcp4", tcp.Conf("address"))
|
|
||||||
tcp.Assert(e)
|
|
||||||
tcp.listener = l
|
|
||||||
|
|
||||||
log.Printf("%s listen(%d): %v", tcp.Name, tcp.Capi("nlisten", 1), l.Addr())
|
|
||||||
defer tcp.Capi("nlisten", -1)
|
|
||||||
defer log.Println("%s close(%d): %v", tcp.Name, tcp.Capi("nlisten", 0), l.Addr())
|
|
||||||
|
|
||||||
for {
|
|
||||||
c, e := l.Accept()
|
|
||||||
tcp.Assert(e)
|
|
||||||
log.Printf("%s accept(%d): %v<-%v", tcp.Name, tcp.Capi("nclient", 1), c.LocalAddr(), c.RemoteAddr())
|
|
||||||
// defer log.Println(tcp.Name, "close:", tcp.Capi("nclient", -1), c.LocalAddr(), "<-", c.RemoteAddr())
|
|
||||||
|
|
||||||
msg := m.Spawn(m.Context, c.RemoteAddr().String()).Put("option", "io", c)
|
|
||||||
msg.Cmd("accept", c.RemoteAddr().String(), "tcp")
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (tcp *TCP) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|
||||||
c.Caches = map[string]*ctx.Cache{
|
|
||||||
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
|
|
||||||
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
|
|
||||||
}
|
|
||||||
c.Configs = map[string]*ctx.Config{
|
|
||||||
"address": &ctx.Config{Name: "address", Value: arg[0], Help: "监听地址"},
|
|
||||||
}
|
|
||||||
|
|
||||||
s := new(TCP)
|
|
||||||
s.Context = c
|
|
||||||
return s
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (tcp *TCP) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
|
|
||||||
if c, ok := m.Data["result"].(net.Conn); ok && m.Target == tcp.Context {
|
|
||||||
c.Close()
|
|
||||||
delete(m.Data, "result")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if c, ok := m.Data["detail"].(net.Conn); ok && m.Context == tcp.Context {
|
|
||||||
c.Close()
|
|
||||||
delete(m.Data, "detail")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "tcp", Help: "网络连接",
|
|
||||||
Caches: map[string]*ctx.Cache{
|
|
||||||
"nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"},
|
|
||||||
"nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "连接数量"},
|
|
||||||
},
|
|
||||||
Configs: map[string]*ctx.Config{
|
|
||||||
"address": &ctx.Config{Name: "address", Value: "", Help: "监听地址"},
|
|
||||||
},
|
|
||||||
Commands: map[string]*ctx.Command{
|
|
||||||
"listen": &ctx.Command{Name: "listen address", Help: "监听端口", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
switch len(arg) { // {{{
|
|
||||||
case 0:
|
|
||||||
for k, s := range m.Target.Contexts {
|
|
||||||
m.Echo("%s %s\n", k, s.Server.(*TCP).listener.Addr().String())
|
|
||||||
}
|
|
||||||
case 1:
|
|
||||||
m.Start(arg...)
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"dial": &ctx.Command{Name: "dial", Help: "建立连接", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
tcp := c.Server.(*TCP) // {{{
|
|
||||||
switch len(arg) {
|
|
||||||
case 0:
|
|
||||||
for i, v := range tcp.Resource {
|
|
||||||
conn := v.Data["result"].(net.Conn)
|
|
||||||
m.Echo(tcp.Name, "conn: %s %s -> %s\n", i, conn.LocalAddr(), conn.RemoteAddr())
|
|
||||||
}
|
|
||||||
case 2:
|
|
||||||
conn, e := net.Dial("tcp", arg[0])
|
|
||||||
c.Assert(e)
|
|
||||||
log.Println(tcp.Name, "dial:", conn.LocalAddr(), "->", conn.RemoteAddr())
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
"exit": &ctx.Command{Name: "exit", Help: "退出", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
tcp, ok := m.Target.Server.(*TCP) // {{{
|
|
||||||
if !ok {
|
|
||||||
tcp, ok = m.Context.Server.(*TCP)
|
|
||||||
}
|
|
||||||
if ok {
|
|
||||||
tcp.Context.Exit(m)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
tcp := &TCP{}
|
|
||||||
tcp.Context = Index
|
|
||||||
ctx.Index.Register(Index, tcp)
|
|
||||||
}
|
|
@ -1,167 +0,0 @@
|
|||||||
package web // {{{
|
|
||||||
// }}}
|
|
||||||
import ( // {{{
|
|
||||||
"context"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"path"
|
|
||||||
)
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
type Request struct {
|
|
||||||
R *http.Request
|
|
||||||
W http.ResponseWriter
|
|
||||||
X interface{}
|
|
||||||
*WEB
|
|
||||||
}
|
|
||||||
|
|
||||||
type WEB struct {
|
|
||||||
Run bool
|
|
||||||
|
|
||||||
*Request
|
|
||||||
|
|
||||||
*http.ServeMux
|
|
||||||
*http.Server
|
|
||||||
|
|
||||||
*ctx.Context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{
|
|
||||||
log.Println()
|
|
||||||
log.Println(web.Name, r.RemoteAddr, r.Method, r.URL)
|
|
||||||
defer log.Println()
|
|
||||||
|
|
||||||
if web.Conf("logheaders") == "yes" {
|
|
||||||
for k, v := range r.Header {
|
|
||||||
log.Println(k+":", v[0])
|
|
||||||
}
|
|
||||||
log.Println()
|
|
||||||
}
|
|
||||||
|
|
||||||
r.ParseForm()
|
|
||||||
if len(r.PostForm) > 0 {
|
|
||||||
for k, v := range r.PostForm {
|
|
||||||
log.Printf("%s: %s", k, v[0])
|
|
||||||
}
|
|
||||||
log.Println()
|
|
||||||
}
|
|
||||||
|
|
||||||
web.ServeMux.ServeHTTP(w, r)
|
|
||||||
|
|
||||||
if web.Conf("logheaders") == "yes" {
|
|
||||||
for k, v := range w.Header() {
|
|
||||||
log.Println(k+":", v[0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
func (web *WEB) Begin(m *ctx.Message) ctx.Server { // {{{
|
|
||||||
return web
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (web *WEB) Start(m *ctx.Message) bool { // {{{
|
|
||||||
|
|
||||||
if !web.Run {
|
|
||||||
if web.Conf("directory") != "" {
|
|
||||||
web.Handle("/", http.FileServer(http.Dir(web.Conf("directory"))))
|
|
||||||
log.Println(web.Name, "directory:", web.Conf("directory"))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range web.Contexts {
|
|
||||||
if s, ok := v.Server.(http.Handler); ok {
|
|
||||||
log.Println(web.Name, "route:", v.Conf("route"), "->", v.Name)
|
|
||||||
web.Handle(v.Conf("route"), http.StripPrefix(path.Dir(v.Conf("route")), s))
|
|
||||||
v.Start(m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
web.Run = true
|
|
||||||
|
|
||||||
if m.Target != web.Context {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
web.Server = &http.Server{Addr: web.Conf("address"), Handler: web}
|
|
||||||
log.Println(web.Name, "protocol:", web.Conf("protocol"))
|
|
||||||
log.Println(web.Name, "address:", web.Conf("address"))
|
|
||||||
|
|
||||||
if web.Conf("protocol") == "https" {
|
|
||||||
log.Println(web.Name, "cert:", web.Conf("cert"))
|
|
||||||
log.Println(web.Name, "key:", web.Conf("key"))
|
|
||||||
web.Server.ListenAndServeTLS(web.Conf("cert"), web.Conf("key"))
|
|
||||||
} else {
|
|
||||||
web.Server.ListenAndServe()
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (web *WEB) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
|
|
||||||
c.Caches = map[string]*ctx.Cache{}
|
|
||||||
c.Configs = map[string]*ctx.Config{}
|
|
||||||
c.Commands = map[string]*ctx.Command{}
|
|
||||||
|
|
||||||
s := new(WEB)
|
|
||||||
s.Context = c
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
func (web *WEB) Exit(m *ctx.Message, arg ...string) bool { // {{{
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// }}}
|
|
||||||
|
|
||||||
var Index = &ctx.Context{Name: "web", Help: "网页服务",
|
|
||||||
Caches: map[string]*ctx.Cache{
|
|
||||||
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
|
|
||||||
},
|
|
||||||
Configs: map[string]*ctx.Config{
|
|
||||||
"logheaders": &ctx.Config{Name: "logheaders", Value: "yes", Help: "日志输出请求头"},
|
|
||||||
"directory": &ctx.Config{Name: "directory", Value: "./", Help: "服务目录"},
|
|
||||||
"protocol": &ctx.Config{Name: "protocol", Value: "https", Help: "服务协议"},
|
|
||||||
"address": &ctx.Config{Name: "address", Value: ":443", Help: "监听地址"},
|
|
||||||
"route": &ctx.Config{Name: "route", Value: "/", Help: "请求路径"},
|
|
||||||
"default": &ctx.Config{Name: "default", Value: "hello web world", Help: "默认响应体"},
|
|
||||||
},
|
|
||||||
Commands: map[string]*ctx.Command{
|
|
||||||
"listen": &ctx.Command{Name: "listen [route [address protocol [directory]]]", Help: "开启网页服务", Hand: func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
|
|
||||||
s, ok := m.Target.Server.(*WEB) // {{{
|
|
||||||
if !ok {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(arg) > 0 {
|
|
||||||
s.Conf("route", arg[0])
|
|
||||||
}
|
|
||||||
if len(arg) > 2 {
|
|
||||||
s.Conf("address", arg[1])
|
|
||||||
s.Conf("protocol", arg[2])
|
|
||||||
}
|
|
||||||
if len(arg) > 3 {
|
|
||||||
s.Conf("directory", arg[3])
|
|
||||||
}
|
|
||||||
go s.Start(m)
|
|
||||||
|
|
||||||
return ""
|
|
||||||
// }}}
|
|
||||||
}},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
web := &WEB{}
|
|
||||||
web.Context = Index
|
|
||||||
ctx.Index.Register(Index, web)
|
|
||||||
|
|
||||||
web.ServeMux = http.NewServeMux()
|
|
||||||
web.HandleFunc("/hi", func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Write([]byte(web.Conf("default")))
|
|
||||||
})
|
|
||||||
}
|
|
@ -2,11 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
// _ "context/aaa"
|
|
||||||
_ "context/cli"
|
_ "context/cli"
|
||||||
// _ "context/tcp"
|
|
||||||
// _ "context/web"
|
|
||||||
// _ "context/web/mp"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user