-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.go
executable file
·110 lines (98 loc) · 3.24 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package goweb
import (
"log"
"net/http"
"time"
)
// AppServer wraps net/http.Server to handle logs, errors, router registration
type AppServer struct {
Server *http.Server
ServeMux *http.ServeMux
LogHandlerFunc LogHandlerFunc
ErrorHandlerFunc ErrorHandlerFunc
basePatternRouterMap map[string]([]*Router)
}
// AppServerConfig config structure for AppServer
type AppServerConfig struct {
Addr string // Address this app server listens to, eg: :80
ReadTimeout time.Duration // ReadTimeout for request header
WriteTimeout time.Duration // WriteTimeout for response
MaxHeaderBytes int // Max Number of bytes of the request header
LogHandlerFunc LogHandlerFunc
ErrorHandlerFunc ErrorHandlerFunc
}
// NewAppServer create a new AppServer instance
func NewAppServer(config *AppServerConfig) *AppServer {
mux := http.NewServeMux()
server := &http.Server{
Addr: config.Addr,
Handler: mux,
ReadTimeout: config.ReadTimeout,
WriteTimeout: config.WriteTimeout,
MaxHeaderBytes: config.MaxHeaderBytes,
}
appServer := &AppServer{
Server: server,
ServeMux: mux,
LogHandlerFunc: config.LogHandlerFunc,
ErrorHandlerFunc: config.ErrorHandlerFunc,
basePatternRouterMap: make(map[string]([]*Router), 0),
}
return appServer
}
// ResponseText echo given text for a given url, this is useful for cases like ping/pong healthcheck
func (server *AppServer) ResponseText(url string, responseStr string) {
server.AddRouter(url, func(req *Request, resp *Response, context *RequestContext) error {
resp.WriteString(responseStr)
return nil
}, &RouterConfig{
DisableAccessLog: true,
})
}
// AddController register controller to this AppServer
func (server *AppServer) AddController(pattern string, ins interface{}, methodMap map[string]string) {
c, err := WrapController(ins, methodMap)
if err != nil {
panic(err)
}
server.AddRouter(pattern, c, &RouterConfig{
DisableAccessLog: false,
})
}
// AddHub add router hub to the server
func (server *AppServer) AddHub(hub *RouterHub) {
server.Handle(hub.BasePattern, hub, false)
}
func (server *AppServer) AddRouter(pattern string, handlerFunc RequestHandlerFunc, config *RouterConfig) {
router := NewRouter(pattern, handlerFunc, config)
list, found := server.basePatternRouterMap[router.PathConfig.PatternString()]
if !found {
list = make([]*Router, 0)
}
list = append(list, router)
server.basePatternRouterMap[router.PathConfig.PatternString()] = list
}
func (server *AppServer) Handle(pattern string, h RequestHandler, disableAccessLog bool) {
server.ServeMux.Handle(pattern, &RouterAdapter{
RequestHandler: h,
AppServer: server,
DisableAccessLog: disableAccessLog,
})
}
// Start start the AppServer
func (server *AppServer) Start() {
// process routers
for basePattern, list := range server.basePatternRouterMap {
if len(list) == 1 && list[0].PathConfig.IsPlainPath() {
server.Handle(basePattern, list[0], list[0].Config.DisableAccessLog) // TODO: fix ugly access
} else {
// need a hub
hub := NewRouterHub(basePattern)
for _, router := range list {
hub.AddRouter(router)
}
server.AddHub(hub)
}
}
log.Fatal(server.Server.ListenAndServe())
}