fix panic
This commit is contained in:
parent
212949154d
commit
f437bb300c
|
@ -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": "/",
|
||||||
|
|
42
gohttp.go
42
gohttp.go
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
5
main.go
5
main.go
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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 == "" {
|
||||||
|
|
|
@ -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 == "/" {
|
||||||
|
|
|
@ -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": "/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
Binary file not shown.
|
@ -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
|
|
@ -0,0 +1 @@
|
||||||
|
39527
|
11
util.go
11
util.go
|
@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue