1
0
forked from x/icebergs
icebergs/base/web/web.go
2022-11-26 19:35:27 +08:00

133 lines
3.7 KiB
Go

package web
import (
"net"
"net/http"
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
"shylinux.com/x/toolkits/task"
)
type Frame struct {
*ice.Message
*http.Client
*http.Server
*http.ServeMux
send ice.Messages
lock task.Lock
}
func (frame *Frame) getSend(key string) (*ice.Message, bool) {
defer frame.lock.RLock()()
msg, ok := frame.send[key]
return msg, ok
}
func (frame *Frame) addSend(key string, msg *ice.Message) string {
defer frame.lock.Lock()()
frame.send[key] = msg
return key
}
func (frame *Frame) delSend(key string) {
defer frame.lock.Lock()()
delete(frame.send, key)
}
func (frame *Frame) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if _serve_main(frame.Message, w, r) {
frame.ServeMux.ServeHTTP(w, r)
}
}
func (frame *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server {
return &Frame{}
}
func (frame *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
frame.send = ice.Messages{}
return frame
}
func (frame *Frame) Start(m *ice.Message, arg ...string) bool {
meta := logs.FileLineMeta("")
list := map[*ice.Context]string{}
m.Travel(func(p *ice.Context, c *ice.Context) {
if f, ok := c.Server().(*Frame); ok {
if f.ServeMux != nil {
return
}
f.ServeMux = http.NewServeMux()
msg := m.Spawn(c)
if pf, ok := p.Server().(*Frame); ok && pf.ServeMux != nil {
route := ice.PS + c.Name + ice.PS
msg.Log(ROUTE, "%s <= %s", p.Name, route, meta)
pf.Handle(route, http.StripPrefix(path.Dir(route), f))
list[c] = path.Join(list[p], route)
}
m.Confm(SERVE, kit.Keym(nfs.PATH), func(key string, value string) {
m.Log(ROUTE, "%s <- %s <- %s", c.Name, key, value, meta)
f.Handle(key, http.StripPrefix(key, http.FileServer(http.Dir(value))))
})
m.Travel(func(p *ice.Context, _c *ice.Context, key string, cmd *ice.Command) {
if c != _c || key[0] != '/' {
return
}
msg.Log(ROUTE, "%s <- %s", c.Name, key, meta)
ice.Info.Route[path.Join(list[c], key)] = ctx.FileURI(cmd.GetFileLine())
f.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) {
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) { _serve_handle(key, cmd, msg, w, r) })
})
})
}
})
gdb.Event(m, SERVE_START, arg)
defer gdb.Event(m, SERVE_STOP)
frame.Message, frame.Server = m, &http.Server{Handler: frame}
switch cb := m.OptionCB("").(type) {
case func(http.Handler):
cb(frame) // 启动框架
default:
mdb.HashCreate(m, mdb.NAME, WEB, arg, m.OptionSimple(tcp.PROTO, ice.DEV), cli.STATUS, tcp.START)
m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, WEB, m.OptionSimple(mdb.NAME, tcp.HOST, tcp.PORT), func(l net.Listener) {
defer mdb.HashModify(m, m.OptionSimple(mdb.NAME), cli.STATUS, tcp.STOP)
mdb.HashSelectTarget(m, m.Option(mdb.NAME), func() ice.Any { return l })
m.Warn(frame.Server.Serve(l)) // 启动服务
})
}
return true
}
func (frame *Frame) Close(m *ice.Message, arg ...string) bool {
return true
}
const (
WEBSITE = "website"
CODE_INNER = "web.code.inner"
WIKI_WORD = "web.wiki.word"
)
const WEB = "web"
var Index = &ice.Context{Name: WEB, Help: "网络模块"}
func init() {
ice.Index.Register(Index, &Frame{},
BROAD, SERVE, SPACE, DREAM,
SHARE, CACHE, SPIDE, ROUTE,
)
}
func ApiAction(arg ...string) ice.Actions {
return ice.Actions{kit.Select(ice.PS, arg, 0): {}}
}
func P(arg ...string) string { return path.Join(ice.PS, path.Join(arg...)) }
func PP(arg ...string) string { return P(arg...) + ice.PS }