fix panic

This commit is contained in:
程广 2023-12-13 09:22:05 +08:00
parent 212949154d
commit f437bb300c
12 changed files with 137 additions and 18 deletions

View File

@ -16,11 +16,14 @@
} }
}, },
"admin" : { "admin" : {
"port" : 8088 "name": "admin",
"port" : 8088,
"username": "admin",
"password": "admin"
}, },
"servers":[{ "servers":[{
"port" : 8080, "port" : 8080,
"servername":"test", "name":"test",
"paths":[ "paths":[
{ {
"path": "/", "path": "/",

View File

@ -21,16 +21,12 @@ func (g *GoHttp) Start() {
g.logger = gologger.GetLogger("Server") g.logger = gologger.GetLogger("Server")
g.logger.Info("start gohttpd") g.logger.Info("start gohttpd")
// if g.conf != nil { // if g.conf != nil {
port := model.DefaultAdminConfig.Port
if conf.Admin != nil {
port = conf.Admin.Port
}
g.makeServer("admin", port, admin.AdminServerMux) g.makeServer(conf.Admin, admin.AdminServerMux)
for _, server := range conf.Servers { for _, server := range conf.Servers {
sHandler := g.assembleServerMux(server.Paths) sHandler := g.assembleServerMux(server.Paths)
g.makeServer(server.ServerName, server.Port, sHandler) g.makeServer(server, sHandler)
} }
for _, listener := range server.ServerManager { for _, listener := range server.ServerManager {
@ -41,11 +37,17 @@ func (g *GoHttp) Start() {
g.logger.Info("gohttpd start success") g.logger.Info("gohttpd start success")
} }
func (g *GoHttp) makeServer(name string, port int, mux http.Handler) { func (g *GoHttp) makeServer(conf *model.HttpServerConfig, mux http.Handler) {
s := &http.Server{ s := &http.Server{
Handler: mux, Handler: mux,
} }
server.AddServer(name, s, port) name := conf.Name
port := conf.Port
ss := &server.Server{
Server: s,
Conf: conf,
}
server.AddServer(name, ss, port)
} }
func (g *GoHttp) assembleServerMux(p []model.HttpPath) http.Handler { func (g *GoHttp) assembleServerMux(p []model.HttpPath) http.Handler {
@ -78,7 +80,31 @@ func LoadConfig(configPath string) {
// read content from cpath // read content from cpath
content, _ := os.ReadFile(cpath) content, _ := os.ReadFile(cpath)
json.Unmarshal(content, &model.Config) json.Unmarshal(content, &model.Config)
//normalize path in config
for _, appender := range model.Config.Logging.Appenders {
if appender.Type == "file" {
appender.Options["file"] = NormalizePath(appender.Options["file"].(string))
}
}
normalizeServer(model.Config.Admin)
for _, server := range model.Config.Servers {
normalizeServer(server)
}
gologger.Configure(model.Config.Logging) gologger.Configure(model.Config.Logging)
logger := gologger.GetLogger("Server") logger := gologger.GetLogger("Server")
logger.Info("Load config success") logger.Info("Load config success")
} }
func normalizeServer(server *model.HttpServerConfig) {
for _, path := range server.Paths {
if path.Root != "" {
path.Root = NormalizePath(path.Root)
}
}
if server.CertFile != "" {
server.CertFile = NormalizePath(server.CertFile)
}
if server.KeyFile != "" {
server.KeyFile = NormalizePath(server.KeyFile)
}
}

View File

@ -14,8 +14,10 @@ func main() {
daemon.Start() daemon.Start()
} }
var waiter chan os.Signal
func start(g *godaemon.GoDaemon) { func start(g *godaemon.GoDaemon) {
var waiter = make(chan os.Signal, 1) // buffered channel waiter = make(chan os.Signal, 1) // buffered channel
signal.Notify(waiter, syscall.SIGTERM, syscall.SIGINT) signal.Notify(waiter, syscall.SIGTERM, syscall.SIGINT)
httpd := &GoHttp{} httpd := &GoHttp{}
@ -24,6 +26,7 @@ func start(g *godaemon.GoDaemon) {
// blocks here until there's a signal // blocks here until there's a signal
<-waiter <-waiter
httpd.logger.Info("Exit")
} }
func stop(g *godaemon.GoDaemon) { func stop(g *godaemon.GoDaemon) {

View File

@ -23,6 +23,8 @@ type HttpServerConfig struct {
Paths []HttpPath Paths []HttpPath
Username string `json:"username"` Username string `json:"username"`
Password string `json:"password"` Password string `json:"password"`
CertFile string `json:"certfile"`
KeyFile string `json:"keyfile"`
} }
type GoHttpdConfig struct { type GoHttpdConfig struct {

View File

@ -10,7 +10,7 @@ import (
"bufio" "bufio"
"io" "io"
"git.pyer.club/kingecg/gologger" "git.pyer.club/kingecg/gohttpd/model"
logger "git.pyer.club/kingecg/gologger" logger "git.pyer.club/kingecg/gologger"
"github.com/soheilhy/cmux" "github.com/soheilhy/cmux"
) )
@ -30,13 +30,17 @@ func makeMatcher(name string, s *ServerListener) cmux.Matcher {
} }
} }
type Server struct {
Conf *model.HttpServerConfig
*http.Server
}
type ServerListener struct { type ServerListener struct {
port int port int
listener cmux.CMux listener cmux.CMux
servers map[string]*http.Server servers map[string]*Server
} }
func (s *ServerListener) AddServer(name string, server *http.Server) { func (s *ServerListener) AddServer(name string, server *Server) {
s.servers[name] = server s.servers[name] = server
} }
@ -51,6 +55,9 @@ func (s *ServerListener) StartServer(name string) error {
} }
l := s.listener.Match(makeMatcher(name, s)) l := s.listener.Match(makeMatcher(name, s))
if server.Conf.CertFile != "" && server.Conf.KeyFile != "" {
return server.ServeTLS(l, server.Conf.CertFile, server.Conf.KeyFile)
}
return server.Serve(l) return server.Serve(l)
} }
@ -75,7 +82,7 @@ func (s *ServerListener) ShutDown() {
} }
func (s *ServerListener) Serve() { func (s *ServerListener) Serve() {
l := gologger.GetLogger("Listener") l := logger.GetLogger("Listener")
l.Debug("listen on :", s.port) l.Debug("listen on :", s.port)
go s.listener.Serve() go s.listener.Serve()
} }
@ -89,11 +96,11 @@ func NewServerListener(port int) *ServerListener {
l.Error("Listen error:", err) l.Error("Listen error:", err)
} }
muxer := cmux.New(l) muxer := cmux.New(l)
s := &ServerListener{port: port, listener: muxer, servers: make(map[string]*http.Server)} s := &ServerListener{port: port, listener: muxer, servers: make(map[string]*Server)}
return s return s
} }
func AddServer(name string, server *http.Server, port int) { func AddServer(name string, server *Server, port int) {
listenStr := fmt.Sprintf(":%d", port) listenStr := fmt.Sprintf(":%d", port)
listener, ok := ServerManager[listenStr] listener, ok := ServerManager[listenStr]
if !ok { if !ok {

View File

@ -2,9 +2,12 @@ package server
import ( import (
"context" "context"
"fmt"
"net/http" "net/http"
"sort" "sort"
"strings" "strings"
"git.pyer.club/kingecg/gologger"
) )
type RequestCtxKey string type RequestCtxKey string
@ -25,11 +28,14 @@ func (route *Route) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
func (route *Route) Match(r *http.Request) bool { func (route *Route) Match(r *http.Request) bool {
l := gologger.GetLogger("Route")
l.Debug(fmt.Sprintf("match route: %s %s", r.Method, r.URL.Path))
if route.Method != "" && route.Method != r.Method { if route.Method != "" && route.Method != r.Method {
l.Debug("method not match")
return false return false
} }
if route.matcher != nil { if route.matcher != nil && route.matcher.Reg != nil {
params, matched := MatchUrlParam(r.URL.Path, route.matcher) params, matched := MatchUrlParam(r.URL.Path, route.matcher)
if matched { if matched {
ctx := r.Context() ctx := r.Context()
@ -39,6 +45,7 @@ func (route *Route) Match(r *http.Request) bool {
} }
return true return true
} }
l.Debug("Not match matcher reg")
return false return false
} }
if route.Path == "" { if route.Path == "" {

View File

@ -4,6 +4,8 @@ import (
"net/url" "net/url"
"regexp" "regexp"
"strings" "strings"
"git.pyer.club/kingecg/gologger"
) )
type UrlParamMatcher struct { type UrlParamMatcher struct {
@ -49,6 +51,8 @@ func ParseUrl(u string) UrlParamMatcher {
} }
func MatchUrlParam(u string, matcher *UrlParamMatcher) (map[string]string, bool) { func MatchUrlParam(u string, matcher *UrlParamMatcher) (map[string]string, bool) {
l := gologger.GetLogger("URLMatcher")
l.Debug("Match for ", u)
if matcher.Reg != nil { if matcher.Reg != nil {
uo, _ := url.Parse(u) uo, _ := url.Parse(u)
if uo.Path == "" || uo.Path == "/" { if uo.Path == "" || uo.Path == "/" {

43
target/config.json Normal file
View File

@ -0,0 +1,43 @@
{
"logging" :{
"appenders": {
"out" :{
"type": "file",
"options":{
"file": "gohttpd.log"
}
}
},
"categories": {
"default": {
"appenders": [ "out" ],
"level": "debug"
}
}
},
"admin" : {
"name": "admin",
"port" : 8088,
"username": "admin",
"password": "admin"
},
"servers":[{
"port" : 8080,
"name":"test",
"paths":[
{
"path": "/",
"root": "/home/kingecg/code/gohttp/public/",
"default": "index.html"
},
{
"path": "/ws",
"upstreams":["http://localhost:3000"],
"pathrewrite": {
"replace": "/ws",
"with": "/"
}
}
]
}]
}

BIN
target/gohttpd Executable file

Binary file not shown.

12
target/gohttpd.log Normal file
View File

@ -0,0 +1,12 @@
[2023-12-12 15:27:25] Server : info - Load config success
[2023-12-12 15:27:25] Server : info - Load config success
[2023-12-12 15:27:25] daemon : debug - Starting new task
[2023-12-12 15:27:25] Server : info - Load config success
[2023-12-12 15:27:25] Server : info - start gohttpd
[2023-12-12 15:27:25] Listener : debug - listen on :8088
[2023-12-12 15:27:25] Listener : debug - listen on :8080
[2023-12-12 15:27:25] Server : info - gohttpd start success
[2023-12-12 15:27:37] Route : debug - match route: GET /about
[2023-12-12 18:31:09] Server : info - Exit
[2023-12-12 18:31:09] daemon : debug - Stop it
[2023-12-12 18:31:09] daemon : debug - daemon is stopped, exit now

1
target/gohttpd.pid Normal file
View File

@ -0,0 +1 @@
39527

11
util.go
View File

@ -13,3 +13,14 @@ func GetExecDir() string {
} }
return filepath.Dir(execPath) return filepath.Dir(execPath)
} }
func NormalizePath(path string) string {
// return filepath.ToSlash(filepath.Clean(path))
p := filepath.ToSlash(path)
if filepath.IsAbs(p) {
return p
} else {
return filepath.Join(GetExecDir(), p)
}
}