// Copyright (C) 2019 Marius Schellenberger package server import ( "bytes" "context" "errors" "git.giftfish.de/ston1th/docstore/pkg/core" "git.giftfish.de/ston1th/docstore/pkg/db" "git.giftfish.de/ston1th/docstore/pkg/log" "git.giftfish.de/ston1th/godrop/v2" "git.giftfish.de/ston1th/jwt/v3" "github.com/gorilla/mux" "html/template" "net" "net/http" "time" ) const ( cookieName = "gosession" ) type HTTPServer struct { Config core.Config listener net.Listener srv *http.Server handler http.Handler DB *db.DB JWT *jwt.JWT templ map[string]*template.Template res map[string][]byte } func NewHTTPServer(cfg core.Config, l net.Listener) (srv *HTTPServer) { srv = &HTTPServer{ Config: cfg, listener: l, handler: srv.buildRoutes(), } srv.loadTemplates() srv.srv = &http.Server{} return } func (s *HTTPServer) Start() (err error) { s.DB, err = db.New(s.Config) if err != nil { return errors.New("db: " + err.Error()) } err = godrop.UnveilBlock() if err != nil { return } if s.Config.Secret != "" { s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, bytes.NewBufferString(s.Config.Secret)) } else { s.JWT, err = jwt.New(jwt.DefaultExpiry, s.DB, nil) } if err != nil { return errors.New("server: " + err.Error()) } if !s.DB.UserExists() { s.srv.Handler = s.register() } else { s.srv.Handler = s.handler } go func() { log.Println(s.srv.Serve(s.listener)) }() return } func (s *HTTPServer) Stop() error { s.DB.Close() s.JWT.Stop() ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() return s.srv.Shutdown(ctx) } func (s *HTTPServer) register() http.Handler { m := mux.NewRouter() m.NotFoundHandler = ®isterNotFoundHandler{s} for _, v := range register { m.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...) } return m } func (s *HTTPServer) buildRoutes() http.Handler { m := mux.NewRouter() m.NotFoundHandler = ¬FoundHandler{s} for _, v := range routes { m.HandleFunc(v.Path, s.contextWrapper(v.Handler)).Methods(v.Methods...) } return m } func (s *HTTPServer) contextWrapper(h ctxHandler) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { ctx := newContext(w, r, s) if ctx == nil { return } h(ctx) } }