1
0
forked from x/ContextOS

vpn mod context/web 网页服务支持多主机多路径

This commit is contained in:
shaoying 2017-11-06 18:12:02 +08:00
parent f1925e3ab9
commit 7afce79a45
6 changed files with 162 additions and 56 deletions

View File

@ -23,31 +23,36 @@ snippet c
import ( import (
"context" "context"
_ "context/cli"
) )
type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct { type `toupper(substitute(expand("%:t"), ".go", "", ""))` struct {
*ctx.Context *ctx.Context
*ctx.CTX
} }
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin() bool { func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Begin(m *ctx.Message) ctx.Server {
return nil
}
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start(m *ctx.Message) bool {
return true return true
} }
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Start() bool { func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server {
return true
}
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Spawn(c *ctx.Context, arg ...string) ctx.Server {
c.Caches = map[string]*ctx.Cache{} c.Caches = map[string]*ctx.Cache{}
c.Configs = map[string]*ctx.Config{} c.Configs = map[string]*ctx.Config{}
c.Commands = map[string]*ctx.Command{} c.Commands = map[string]*ctx.Command{}
s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`) s := new(`toupper(substitute(expand("%:t"), ".go", "", ""))`)
s.CTX = ctx.Ctx
s.Context = c s.Context = c
return s return s
} }
func (`Filename()` *`toupper(substitute(expand("%:t"), ".go", "", ""))`) Exit(m *ctx.Message, arg ...string) bool {
return true
}
var Index = &ctx.Context{Name: "`Filename()`", Help: "${1}", var Index = &ctx.Context{Name: "`Filename()`", Help: "${1}",
Caches: map[string]*ctx.Cache{}, Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{}, Configs: map[string]*ctx.Config{},
@ -56,7 +61,6 @@ snippet c
func init() { func init() {
`Filename()` := &`toupper(substitute(expand("%:t"), ".go", "", ""))`{} `Filename()` := &`toupper(substitute(expand("%:t"), ".go", "", ""))`{}
`Filename()`.CTX = ctx.Ctx
`Filename()`.Context = Index `Filename()`.Context = Index
ctx.Index.Register(Index, `Filename()`) ctx.Index.Register(Index, `Filename()`)
} }

View File

@ -4,3 +4,6 @@ alias @ config
alias $ cache alias $ cache
alias & server alias & server
alias * message alias * message
~web
listen :9393 etc

View File

@ -1,10 +1,13 @@
package cli package cli // {{{
// }}}
import ( // {{{ import ( // {{{
"bufio" "bufio"
"context" "context"
_ "context/tcp"
_ "context/web"
"fmt" "fmt"
"io" "io"
"log"
"os" "os"
"strconv" "strconv"
"strings" "strings"
@ -143,7 +146,6 @@ func (cli *CLI) echo(str string, arg ...interface{}) { // {{{
func (cli *CLI) Begin(m *ctx.Message) ctx.Server { // {{{ func (cli *CLI) Begin(m *ctx.Message) ctx.Server { // {{{
cli.history = make([]map[string]string, 0, 100) cli.history = make([]map[string]string, 0, 100)
cli.alias = make(map[string]string, 10)
cli.target = cli.Context cli.target = cli.Context
return cli.Server return cli.Server
} }
@ -223,14 +225,17 @@ func (cli *CLI) Exit(m *ctx.Message, arg ...string) bool { // {{{
// }}} // }}}
var Index = &ctx.Context{Name: "cli", Help: "本地控制", var Index = &ctx.Context{Name: "cli", Help: "本地控制", // {{{
Caches: map[string]*ctx.Cache{ Caches: map[string]*ctx.Cache{
"nterm": &ctx.Cache{Name: "nterm", Value: "0", Help: "终端数量"}, "nterm": &ctx.Cache{Name: "nterm", Value: "0", Help: "终端数量"},
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
"nhistory": &ctx.Cache{Name: "nhistory", Value: "0", Help: "终端数量", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string { "nhistory": &ctx.Cache{Name: "nhistory", Value: "0", Help: "终端数量", Hand: func(c *ctx.Context, x *ctx.Cache, arg ...string) string {
if cli, ok := c.Server.(*CLI); ok { if cli, ok := c.Server.(*CLI); ok { // {{{
return fmt.Sprintf("%d", len(cli.history)) return fmt.Sprintf("%d", len(cli.history))
} }
return ""
return x.Value
// }}}
}}, }},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
@ -260,7 +265,8 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
cli, ok := c.Server.(*CLI) // {{{ cli, ok := c.Server.(*CLI) // {{{
switch len(arg) { switch len(arg) {
case 0: case 0:
cs := []*ctx.Context{m.Target} // cs := []*ctx.Context{m.Target}
cs := []*ctx.Context{m.Target.Root}
for i := 0; i < len(cs); i++ { for i := 0; i < len(cs); i++ {
if len(cs[i].Contexts) > 0 { if len(cs[i].Contexts) > 0 {
m.Echo("%s: ", cs[i].Name) m.Echo("%s: ", cs[i].Name)
@ -360,6 +366,16 @@ 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}
for i := 0; i < len(cs); i++ {
if x, ok := cs[i].Caches["status"]; ok {
m.Echo("%s(%s): %s\n", cs[i].Name, x.Value, cs[i].Help)
}
for _, v := range cs[i].Contexts {
cs = append(cs, v)
}
}
return "server start" return "server start"
case 1: case 1:
switch arg[0] { switch arg[0] {
@ -415,6 +431,7 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
case 1: case 1:
n, e := strconv.Atoi(arg[0]) n, e := strconv.Atoi(arg[0])
if e == nil && 0 <= n && n < len(cli.history) { if e == nil && 0 <= n && n < len(cli.history) {
log.Println("shy log why:", cli.history[n]["cli"])
return cli.history[n]["cli"] return cli.history[n]["cli"]
} }
} }
@ -543,8 +560,18 @@ var Index = &ctx.Context{Name: "cli", Help: "本地控制",
Messages: make(chan *ctx.Message, 10), Messages: make(chan *ctx.Message, 10),
} }
func init() { // }}}
cli := &CLI{} func init() { // {{{
cli := &CLI{alias: map[string]string{
"~": "context",
"!": "history",
"@": "config",
"$": "cache",
"&": "server",
"*": "message",
}}
cli.Context = Index cli.Context = Index
ctx.Index.Register(Index, cli) ctx.Index.Register(Index, cli)
} }
// }}}

View File

@ -1,5 +1,5 @@
package ctx package ctx // {{{
// }}}
import ( // {{{ import ( // {{{
"errors" "errors"
"fmt" "fmt"
@ -7,6 +7,7 @@ import ( // {{{
"log" "log"
"os" "os"
"os/exec" "os/exec"
"path"
"regexp" "regexp"
"runtime/debug" "runtime/debug"
"strconv" "strconv"
@ -667,14 +668,15 @@ func (c *Context) Cap(key string, arg ...string) string { // {{{
switch len(arg) { switch len(arg) {
case 0: case 0:
if x.Hand != nil { if x.Hand != nil {
return x.Hand(c, x) x.Value = x.Hand(c, x)
} }
return x.Value return x.Value
case 1: case 1:
if x.Hand != nil { if x.Hand != nil {
return x.Hand(c, x, x.Value) x.Value = x.Hand(c, x, x.Value)
} } else {
x.Value = arg[0] x.Value = arg[0]
}
return x.Value return x.Value
case 3: case 3:
if s == c { if s == c {
@ -708,7 +710,8 @@ func (c *Context) Capi(key string, arg ...int) int { // {{{
// }}} // }}}
var Index = &Context{Name: "ctx", Help: "根上下文", var Pulse = &Message{Code: 0, Time: time.Now(), Index: 0, Name: "root"}
var Index = &Context{Name: "ctx", Help: "根上下文", // {{{
Caches: map[string]*Cache{ Caches: map[string]*Cache{
"status": &Cache{Name: "status", Value: "stop", Help: "服务状态"}, "status": &Cache{Name: "status", Value: "stop", Help: "服务状态"},
"nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"}, "nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"},
@ -725,44 +728,60 @@ var Index = &Context{Name: "ctx", Help: "根上下文",
"cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"}, "cert": &Config{Name: "cert", Value: "etc/cert.pem", Help: "证书文件"},
"key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"}, "key": &Config{Name: "key", Value: "etc/key.pem", Help: "私钥文件"},
"root": &Config{Name: "root", Value: ".", Help: "工作目录"},
"debug": &Config{Name: "debug", Value: "off", Help: "调试模式"}, "debug": &Config{Name: "debug", Value: "off", Help: "调试模式"},
"start": &Config{Name: "start", Value: "cli", Help: "默认启动模块"}, "start": &Config{Name: "start", Value: "cli", Help: "默认启动模块"},
"init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"}, "init.sh": &Config{Name: "init.sh", Value: "etc/init.sh", Help: "默认启动脚本"},
"bench.log": &Config{Name: "bench.log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, x *Config, arg ...string) string { "bench.log": &Config{Name: "bench.log", Value: "var/bench.log", Help: "默认日志文件", Hand: func(c *Context, x *Config, arg ...string) string {
if len(arg) > 0 { // {{{ if len(arg) > 0 { // {{{
l, e := os.Create(x.Value) if e := os.MkdirAll(path.Dir(arg[0]), os.ModePerm); e == nil {
c.Check(e) if l, e := os.Create(x.Value); e == nil {
log.SetOutput(l) log.SetOutput(l)
} }
}
}
return x.Value return x.Value
// }}} // }}}
}}, }},
}, },
Commands: map[string]*Command{ Commands: map[string]*Command{
"void": &Command{"void", "建立远程连接", func(c *Context, m *Message, key string, arg ...string) string { "void": &Command{"void", "建立远程连接", func(c *Context, m *Message, key string, arg ...string) string {
m.Echo("hello void!\n") m.Echo("hello void!\n") // {{{
return "" return ""
// }}}
}}, }},
}, },
Session: map[string]*Message{"root": Pulse}, Session: map[string]*Message{"root": Pulse},
Resource: []*Message{Pulse}, Resource: []*Message{Pulse},
} }
var Pulse = &Message{Code: 0, Time: time.Now(), Index: 0, Name: "root"} // }}}
func init() { func init() { // {{{
if len(os.Args) > 1 { if len(os.Args) > 1 {
Index.Conf("bench.log", os.Args[1]) Index.Conf("root", os.Args[1])
}
if e := os.MkdirAll(Index.Conf("root"), os.ModePerm); e != nil {
fmt.Println(e)
os.Exit(1)
}
if e := os.Chdir(Index.Conf("root")); e != nil {
fmt.Println(e)
os.Exit(1)
}
if len(os.Args) > 2 {
Index.Conf("bench.log", os.Args[2])
} else { } else {
Index.Conf("bench.log", Index.Conf("bench.log")) Index.Conf("bench.log", Index.Conf("bench.log"))
} }
if len(os.Args) > 2 { if len(os.Args) > 3 {
Index.Conf("init.sh", os.Args[2]) Index.Conf("init.sh", os.Args[3])
} }
if len(os.Args) > 3 { if len(os.Args) > 4 {
Index.Conf("start", os.Args[3]) Index.Conf("start", os.Args[4])
} }
log.Println("\n\n\n") log.Println("\n\n\n")
} }
@ -783,16 +802,21 @@ func Start() {
} }
} }
n := 0
for _, s := range Index.Contexts { for _, s := range Index.Contexts {
if ok, _ := regexp.MatchString(Index.Conf("start"), s.Name); ok { if ok, _ := regexp.MatchString(Index.Conf("start"), s.Name); ok {
n++
go s.Start(Pulse.Spawn(s, s.Name).Put("detail", os.Stdout)) go s.Start(Pulse.Spawn(s, s.Name).Put("detail", os.Stdout))
} }
} }
for { for {
<-Pulse.Wait <-Pulse.Wait
if Index.Capi("nserver", 0) == 0 { n--
if n <= 0 && Index.Capi("nserver", 0) == 0 {
return return
} }
} }
} }
// }}}

View File

@ -1,39 +1,88 @@
package web package web // {{{
// }}}
import ( import ( // {{{
"context" "context"
"context/cli" "log"
"net/http" "net/http"
) )
// }}}
type WEB struct { type WEB struct {
*ctx.Context *ctx.Context
} }
func (web *WEB) Begin() bool { func (web *WEB) Begin(m *ctx.Message) ctx.Server { // {{{
return web
}
// }}}
func (web *WEB) Start(m *ctx.Message) bool { // {{{
mux := http.NewServeMux()
mux.Handle("/", http.FileServer(http.Dir(web.Conf("directory"))))
for _, v := range m.Meta["detail"][2:] {
if h, ok := m.Data[v].(func(http.ResponseWriter, *http.Request)); ok {
mux.HandleFunc(v, h)
}
}
s := &http.Server{Addr: web.Conf("address"), Handler: mux}
s.ListenAndServe()
log.Println(s.ListenAndServe())
return true return true
} }
func (web *WEB) Start() bool {
http.Handle("/", http.FileServer(http.Dir(web.Conf("path")))) // }}}
http.ListenAndServe(web.Conf("address"), nil) func (web *WEB) Spawn(c *ctx.Context, m *ctx.Message, arg ...string) ctx.Server { // {{{
c.Caches = map[string]*ctx.Cache{
"status": &ctx.Cache{Name: "status", Value: "stop", Help: "服务状态"},
}
c.Configs = map[string]*ctx.Config{
"address": &ctx.Config{Name: "listen", Value: arg[0], Help: "监听地址"},
"directory": &ctx.Config{Name: "directory", Value: arg[1], Help: "服务目录"},
}
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 return true
} }
func (web *WEB) Spawn(c *ctx.Context, arg ...string) ctx.Server {
return nil // }}}
}
var Index = &ctx.Context{Name: "web", Help: "网页服务", var Index = &ctx.Context{Name: "web", Help: "网页服务", // {{{
Caches: map[string]*ctx.Cache{}, Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{},
"path": &ctx.Config{Name: "path", Value: "srv", Help: "监听地址"}, Commands: map[string]*ctx.Command{
"address": &ctx.Config{Name: "address", Value: ":9494", Help: "监听地址"}, "listen": &ctx.Command{"listen address directory", "设置监听地址和目录", func(c *ctx.Context, m *ctx.Message, key string, arg ...string) string {
switch len(arg) { // {{{
case 0:
default:
m.Add("detail", "/hi")
m.Put("/hi", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello context world!"))
})
m.Start(m.Meta["detail"][1:]...)
}
return ""
// }}}
}},
}, },
} }
func init() { // }}}
func init() { // {{{
web := &WEB{} web := &WEB{}
web.Context = Index web.Context = Index
cli.Index.Register(Index, web) ctx.Index.Register(Index, web)
} }
// }}}

View File

@ -3,7 +3,6 @@ package main
import ( import (
"context" "context"
_ "context/cli" _ "context/cli"
_ "context/tcp"
) )
func main() { func main() {