router/server.go

106 lines
2.4 KiB
Go
Raw Normal View History

2024-10-07 21:39:42 +00:00
package router
import (
"net/http"
"somehole.com/common/log"
)
type stage uint8
const (
pre stage = iota
main
post
numStages
)
2024-10-08 21:57:25 +00:00
type ServeFunc func(req RequestBuilder, res Response) (errRes ErrorResponse)
2024-10-07 21:39:42 +00:00
type server struct {
prototype Prototype
logger log.Logger
serve [numStages][]ServeFunc
}
2024-10-09 04:15:18 +00:00
func NewServer[RB RequestBuilder, R Response](requestBuilder RB, response R, logger log.Logger, serve func(RB) (R, ErrorResponse)) (srv *server) {
2024-10-07 21:39:42 +00:00
srv = &server{
2024-10-09 04:15:18 +00:00
prototype: Prototype{
PrototypeRequestBuilder: requestBuilder.Prototype(),
PrototypeResponse: response.Prototype(),
},
logger: logger,
serve: [numStages][]ServeFunc{},
2024-10-07 21:39:42 +00:00
}
2024-10-09 04:15:18 +00:00
srv.serve[main] = append(srv.serve[main], func(req RequestBuilder, res Response) (errRes ErrorResponse) {
res, errRes = serve(req.(RB))
return
})
2024-10-07 21:39:42 +00:00
return srv
}
func (srv *server) addServeFunc(when stage, serve ServeFunc) *server {
if srv.serve[when] == nil {
srv.serve[when] = make([]ServeFunc, 0)
}
srv.serve[when] = append(srv.serve[when], serve)
return srv
}
func (srv *server) PreServeFunc(serve ServeFunc) *server {
return srv.addServeFunc(pre, serve)
}
func (srv *server) AddServeFunc(serve ServeFunc) *server {
return srv.addServeFunc(main, serve)
}
func (srv *server) PostServeFunc(serve ServeFunc) *server {
return srv.addServeFunc(post, serve)
}
func (srv *server) handleError(errRes ErrorResponse, w http.ResponseWriter) (ok bool) {
if !errRes.Ok() {
w.WriteHeader(errRes.HttpStatus())
2024-10-09 00:47:49 +00:00
w.Write(errRes.BodyBytes())
2024-10-07 21:39:42 +00:00
srv.logger.Logf(log.LevelError, errRes.String())
return false
}
return true
}
func (srv *server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
p := srv.prototype
2024-10-08 23:15:07 +00:00
req := p.PrototypeRequestBuilder.RequestBuilder()
2024-10-07 21:39:42 +00:00
if ok := srv.handleError(req.Allowed(r.Method), w); !ok {
return
}
2024-10-08 21:57:25 +00:00
if ok := srv.handleError(req.Header(Header(r.Header)), w); !ok {
return
}
2024-10-09 00:45:14 +00:00
if ok := srv.handleError(req.ReadBody(r.Body), w); !ok {
2024-10-07 21:39:42 +00:00
return
}
r.ParseForm()
2024-10-08 21:57:25 +00:00
if ok := srv.handleError(req.Values(Values(r.Form)), w); !ok {
2024-10-07 21:39:42 +00:00
return
}
2024-10-08 23:15:07 +00:00
res := p.PrototypeResponse.Response()
2024-10-07 21:39:42 +00:00
for _, stage := range srv.serve {
for _, s := range stage {
if ok := srv.handleError(s(req, res), w); !ok {
return
}
header := res.Header()
if header != nil {
for key, value := range res.Header() {
for _, v := range value {
w.Header().Add(key, v)
}
}
}
}
}
2024-10-09 00:47:49 +00:00
w.Write(res.BodyBytes())
2024-10-07 21:39:42 +00:00
}