fix mux matcher

This commit is contained in:
kingecg 2023-12-08 22:02:36 +08:00
parent 57225ac59a
commit 61258c5535
8 changed files with 171 additions and 50 deletions

View File

@ -26,7 +26,7 @@ var AdminRoutes = []Route{
var AdminServerMux *server.RestMux
func init() {
AdminServerMux = server.NewRestMux("/admin")
AdminServerMux = server.NewRestMux("/")
// AdminServerMux.routes = make(map[string]map[string]http.HandlerFunc)
for _, route := range AdminRoutes {
AdminServerMux.HandleFunc(route.Method, route.Path, route.Handle)

18
config.json Normal file
View File

@ -0,0 +1,18 @@
{
"logging" :{
"appenders": {
"out" :{
"type": "console"
}
},
"categories": {
"default": {
"appenders": [ "out" ],
"level": "debug"
}
}
},
"admin" : {
"port" : 8088
}
}

61
gohttp.go Normal file
View File

@ -0,0 +1,61 @@
package main
import (
"encoding/json"
"net/http"
"os"
"git.pyer.club/kingecg/gohttpd/admin"
"git.pyer.club/kingecg/gohttpd/model"
"git.pyer.club/kingecg/gohttpd/server"
"git.pyer.club/kingecg/gologger"
)
type GoHttp struct {
conf model.GoHttpdConfig
logger gologger.Logger
}
func (g *GoHttp) Start() {
g.logger.Info("start gohttpd")
// if g.conf != nil {
port := model.DefaultAdminConfig.Port
if g.conf.Admin != nil {
port = g.conf.Admin.Port
}
g.makeServer("admin", port, admin.AdminServerMux)
//TODO: create other server
// }
for _, listener := range server.ServerManager {
listener.Start()
listener.Serve()
}
g.logger.Info("gohttpd start success")
}
func (g *GoHttp) makeServer(name string, port int, mux *server.RestMux) {
s := &http.Server{
Handler: mux,
}
server.AddServer(name, s, port)
}
func (g *GoHttp) Stop() {}
func (g *GoHttp) LoadConfig(configPath string) {
cpath := configPath
if cpath == "" {
cpath = GetExecDir() + "/config.json"
}
// read content from cpath
content, _ := os.ReadFile(cpath)
json.Unmarshal(content, &g.conf)
gologger.Configure(g.conf.Logging)
g.logger = gologger.GetLogger("Server")
g.logger.Info("Load config success")
}

78
main.go
View File

@ -1,55 +1,53 @@
package main
import (
"net/http"
"os"
"os/signal"
"syscall"
admin "git.pyer.club/kingecg/gohttpd/admin"
"git.pyer.club/kingecg/gohttpd/server"
logger "git.pyer.club/kingecg/gologger"
)
func main() {
logger.Configure(logger.LoggersConfig{
Categories: map[string]logger.LogConfig{
"default": {
Level: "debug",
Appenders: []string{
"console",
},
},
"fat": {
Level: "debug",
Appenders: []string{
"console",
"file",
},
},
},
Appenders: map[string]logger.LogAppenderConfig{
"console": {
Type: "console",
},
"file": {
Type: "file",
Options: map[string]interface{}{
"file": "./log/fat.log",
},
},
},
})
defaultLogger := logger.GetLogger("default")
defaultLogger.Info("Listening...")
serverMux := server.NewRestMux("/")
serverMux.HandleMux(admin.AdminServerMux)
go http.ListenAndServe(":8080", serverMux)
defaultLogger.Debug("Next")
// logger.Configure(logger.LoggersConfig{
// Categories: map[string]logger.LogConfig{
// "default": {
// Level: "debug",
// Appenders: []string{
// "console",
// },
// },
// "fat": {
// Level: "debug",
// Appenders: []string{
// "console",
// "file",
// },
// },
// },
// Appenders: map[string]logger.LogAppenderConfig{
// "console": {
// Type: "console",
// },
// "file": {
// Type: "file",
// Options: map[string]interface{}{
// "file": "./log/fat.log",
// },
// },
// },
// })
// defaultLogger := logger.GetLogger("default")
// defaultLogger.Info("Listening...")
// serverMux := server.NewRestMux("/")
// serverMux.HandleMux(admin.AdminServerMux)
// go http.ListenAndServe(":8080", serverMux)
// defaultLogger.Debug("Next")
httpd := &GoHttp{}
httpd.LoadConfig("")
httpd.Start()
var waiter = make(chan os.Signal, 1) // buffered channel
signal.Notify(waiter, syscall.SIGTERM, syscall.SIGINT)
// blocks here until there's a signal
<-waiter
defaultLogger.Info("Listened")
}

View File

@ -1,5 +1,7 @@
package model
import "git.pyer.club/kingecg/gologger"
type HttpPath struct {
Path string `json:"path"`
Root string `json:"root"`
@ -15,8 +17,9 @@ type HttpServerConfig struct {
}
type GoHttpdConfig struct {
Admin HttpServerConfig `json:"admin"`
Servers []HttpServerConfig `json:"servers"`
Logging gologger.LoggersConfig `json:"logging"`
Admin *HttpServerConfig `json:"admin"`
Servers []*HttpServerConfig `json:"servers"`
}
var DefaultAdminConfig HttpServerConfig = HttpServerConfig{

View File

@ -5,6 +5,10 @@ import (
"fmt"
"net"
"net/http"
"strings"
"bufio"
"io"
logger "git.pyer.club/kingecg/gologger"
"github.com/soheilhy/cmux"
@ -12,6 +16,16 @@ import (
var ServerManager map[string]*ServerListener = make(map[string]*ServerListener)
func makeMatcher(name string) cmux.Matcher {
return func(r io.Reader) bool {
req, err := http.ReadRequest(bufio.NewReader(r))
if err != nil {
return false
}
return strings.HasPrefix(req.Host, name)
}
}
type ServerListener struct {
listener cmux.CMux
servers map[string]*http.Server
@ -27,17 +41,19 @@ func (s *ServerListener) StartServer(name string) error {
panic("No named server")
}
l := s.listener.Match(cmux.HTTP1HeaderField("Host", name))
l := s.listener.Match(makeMatcher(name))
return server.Serve(l)
}
func (s *ServerListener) Start() {
for name, _ := range s.servers {
go func(name string) {
err := s.StartServer(name)
if err != nil {
l := logger.GetLogger("ServerListener")
l.Error("Start server error:", name, err)
}
}(name)
}
}
@ -64,3 +80,13 @@ func NewServerListener(port int) *ServerListener {
s := &ServerListener{listener: muxer, servers: make(map[string]*http.Server)}
return s
}
func AddServer(name string, server *http.Server, port int) {
listenStr := fmt.Sprintf(":%d", port)
listener, ok := ServerManager[listenStr]
if !ok {
listener = NewServerListener(port)
ServerManager[listenStr] = listener
}
listener.AddServer(name, server)
}

View File

@ -15,7 +15,7 @@ type RestMux struct {
}
func (mux *RestMux) ServeHTTP(w http.ResponseWriter, r *http.Request) {
_, has := lo.Find[string](mux.rmuxPaths, func(s string) bool {
_, has := lo.Find(mux.rmuxPaths, func(s string) bool {
return strings.HasPrefix(r.URL.Path, s)
})
if has {

15
util.go Normal file
View File

@ -0,0 +1,15 @@
package main
import (
"os"
"path/filepath"
)
func GetExecDir() string {
execPath, err := os.Executable()
if err != nil {
panic(err)
}
return filepath.Dir(execPath)
}