diff --git a/base/tcp/tcp.go b/base/tcp/tcp.go index 0ee7c597..0cac8605 100644 --- a/base/tcp/tcp.go +++ b/base/tcp/tcp.go @@ -1,9 +1,61 @@ package tcp -import ice "shylinux.com/x/icebergs" +import ( + "bytes" + "net" + "net/http" + "strings" + + ice "shylinux.com/x/icebergs" + kit "shylinux.com/x/toolkits" +) const TCP = "tcp" var Index = &ice.Context{Name: TCP, Help: "通信模块"} func init() { ice.Index.Register(Index, nil, HOST, PORT, CLIENT, SERVER) } + +type Buf struct { + buf []byte +} +type PeekConn struct { + net.Conn + *Buf +} + +func (s PeekConn) Read(b []byte) (n int, err error) { + if len(s.buf) == 0 { + return s.Conn.Read(b) + } + if len(s.buf) < len(b) { + copy(b, s.buf) + s.buf = s.buf[:0] + return len(s.buf), nil + } + copy(b, s.buf) + s.buf = s.buf[len(b):] + return len(b), nil +} +func (s PeekConn) Peek(n int) (res []byte) { + b := make([]byte, n) + _n, _ := s.Conn.Read(b) + s.Buf.buf = b[:_n] + return b[:_n] +} +func (s PeekConn) IsHTTP() bool { + if bytes.Equal(s.Peek(4), []byte("GET ")) { + return true + } + return false +} +func (s PeekConn) Redirect(status int, location string) { + DF, NL := ": ", "\r\n" + s.Conn.Write([]byte(strings.Join([]string{ + kit.Format("HTTP/1.1 %d %s", status, http.StatusText(status)), kit.JoinKV(DF, NL, + "Location", location, "Content-Length", "0", + )}, NL) + NL + NL)) +} +func NewPeekConn(c net.Conn) PeekConn { + return PeekConn{Conn: c, Buf: &Buf{}} +} diff --git a/base/web/broad.go b/base/web/broad.go index 201498eb..9802baa9 100644 --- a/base/web/broad.go +++ b/base/web/broad.go @@ -63,7 +63,13 @@ func init() { mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { if arg[0] == BROAD || arg[0] == mdb.FOREACH { m.Cmd("", ice.Maps{ice.MSG_FIELDS: ""}, func(values ice.Maps) { - m.PushSearch(mdb.TEXT, kit.Format("http://%s:%s", values[tcp.HOST], values[tcp.PORT]), values) + switch values[mdb.TYPE] { + case "sshd": + m.PushSearch(mdb.NAME, ice.Render(m, ice.RENDER_SCRIPT, kit.Format("ssh -p %s %s@%s", values[tcp.PORT], m.Option(ice.MSG_USERNAME), values[tcp.HOST])), + mdb.TEXT, kit.Format("http://%s:%s", values[tcp.HOST], values[tcp.PORT]), values) + default: + m.PushSearch(mdb.TEXT, kit.Format("http://%s:%s", values[tcp.HOST], values[tcp.PORT]), values) + } }) } }}, diff --git a/base/web/serve.go b/base/web/serve.go index 78facbf2..29d41af3 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -244,6 +244,9 @@ func init() { PP(ice.PUBLISH): {Name: "/publish/", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { _share_local(m, ice.USR_PUBLISH, path.Join(arg...)) }}, + PP(ice.PUBLISH, "demo"): {Name: "/publish/demo", Help: "定制化", Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { + m.RenderRedirect("/") + }}, PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) { cache := kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")) p := path.Join(cache, path.Join(arg...)) diff --git a/misc/ssh/service.go b/misc/ssh/service.go index ee70a6da..1d3bbb17 100644 --- a/misc/ssh/service.go +++ b/misc/ssh/service.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net" + "net/http" "os" "strings" @@ -67,33 +68,6 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig { return config } -type Buf struct { - buf []byte -} -type Conn struct { - net.Conn - *Buf -} - -func (s Conn) Read(b []byte) (n int, err error) { - if len(s.buf) == 0 { - return s.Conn.Read(b) - } - if len(s.buf) < len(b) { - copy(b, s.buf) - s.buf = s.buf[:0] - return len(s.buf), nil - } - copy(b, s.buf) - s.buf = s.buf[len(b):] - return len(b), nil -} -func (s Conn) Peek(b []byte) (n int, err error) { - n, err = s.Conn.Read(b) - s.buf = append(s.buf, b...) - return n, err -} - func _ssh_accept(m *ice.Message, h string, c net.Conn) { conn, chans, reqs, err := ssh.NewServerConn(c, _ssh_config(m, h)) if m.Warn(err) { @@ -186,9 +160,14 @@ func init() { m.Cmd("", ctx.LOAD, m.OptionSimple(AUTHKEY)) } m.Go(func() { - m.Cmd(web.BROAD, "send", mdb.TYPE, "sshd", mdb.NAME, ice.Info.NodeName, tcp.HOST, m.Cmd(tcp.HOST).Append(aaa.IP), tcp.PORT, m.Option(tcp.PORT)) + m.Cmd(web.BROAD, "send", mdb.TYPE, "sshd", tcp.HOST, m.Cmd(tcp.HOST).Append(aaa.IP), tcp.PORT, m.Option(tcp.PORT)) m.Cmd(tcp.SERVER, tcp.LISTEN, mdb.TYPE, SSH, mdb.NAME, m.Option(tcp.PORT), m.OptionSimple(tcp.PORT), func(c net.Conn) { - m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), Conn{Conn: c, Buf: &Buf{}}) }) + _c := tcp.NewPeekConn(c) + if _c.IsHTTP() { + _c.Redirect(http.StatusTemporaryRedirect, m.Cmdx(web.SPACE, web.DOMAIN)) + return + } + m.Go(func() { _ssh_accept(m, kit.Hashs(m.Option(tcp.PORT)), _c) }) }) }) }},