119 lines
2.4 KiB
Go
119 lines
2.4 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"github.com/gorilla/mux"
|
|
"github.com/gorilla/sessions"
|
|
"html/template"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.giftfish.de/ston1th/gowiki/pkg/db"
|
|
"git.giftfish.de/ston1th/gowiki/pkg/index"
|
|
)
|
|
|
|
const (
|
|
keyLen = 32
|
|
authLen = keyLen * 2
|
|
cookieName = "gosession"
|
|
)
|
|
|
|
type HTTPServer struct {
|
|
Version string
|
|
SecCookie bool
|
|
Store *sessions.CookieStore
|
|
BS *db.BoltStore
|
|
Index *index.Index
|
|
listener net.Listener
|
|
srv *http.Server
|
|
templ map[string]*template.Template
|
|
res map[string][]byte
|
|
}
|
|
|
|
func NewHTTPServer(l net.Listener, versin string, secCookie bool) (srv *HTTPServer) {
|
|
srv = &HTTPServer{
|
|
Version: version,
|
|
SecCookie: secCookie,
|
|
listener: l,
|
|
}
|
|
srv.cookieStore()
|
|
srv.loadTemplates()
|
|
srv.srv = &http.Server{
|
|
Handler: srv.buildRoutes(),
|
|
}
|
|
return
|
|
}
|
|
|
|
func (s *HTTPServer) Start() (err error) {
|
|
s.BS, err = NewBoltStore()
|
|
if err != nil {
|
|
return
|
|
}
|
|
s.Index, err = NewIndex(blevePath)
|
|
if err != nil {
|
|
return
|
|
}
|
|
go func() {
|
|
log.Println(s.srv.Serve(s.listener))
|
|
}()
|
|
return
|
|
}
|
|
|
|
func (s *HTTPServer) Stop() error {
|
|
s.BS.Close()
|
|
s.Index.Close()
|
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
|
defer cancel()
|
|
return s.srv.Shutdown(ctx)
|
|
}
|
|
|
|
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) {
|
|
h(newContext(w, r, s))
|
|
}
|
|
}
|
|
func (s *HTTPServer) cookieStore() {
|
|
options := &sessions.Options{
|
|
Path: "/",
|
|
MaxAge: 3600 * 12,
|
|
Secure: s.SecCookie,
|
|
HttpOnly: true,
|
|
}
|
|
authKey := genKey(authLen)
|
|
encKey := genKey(keyLen)
|
|
s.Store = sessions.NewCookieStore(authKey, encKey)
|
|
s.Store.Options = options
|
|
|
|
go func() {
|
|
for {
|
|
time.Sleep(time.Hour * 12)
|
|
newAuthKey := genKey(authLen)
|
|
newEncKey := genKey(keyLen)
|
|
newStore := sessions.NewCookieStore(newAuthKey, newEncKey, authKey, encKey)
|
|
newStore.Options = options
|
|
|
|
s.Store = newStore
|
|
authKey = newAuthKey
|
|
encKey = newEncKey
|
|
}
|
|
}()
|
|
}
|
|
|
|
func genKey(length int) (bytes []byte) {
|
|
bytes = make([]byte, length)
|
|
if _, err := io.ReadFull(rand.Reader, bytes); err != nil {
|
|
log.Println("genKey:", err)
|
|
}
|
|
return
|
|
}
|