cowyo/config/http.go

106 lines
2.6 KiB
Go

package config
import (
"fmt"
"log"
"encoding/base64"
"net/http"
"github.com/gin-contrib/sessions"
"github.com/jcelliott/lumber"
"github.com/schollz/cowyo/server"
"strings"
)
func (c Config) ListenAndServe() error {
insecurePorts := map[int]bool{}
securePorts := map[int]bool{}
err := make(chan error)
for _, s := range c.Sites {
if !insecurePorts[*s.Port] {
insecurePorts[*s.Port] = true
go func(s SiteConfig) {
err <- http.ListenAndServe(fmt.Sprintf("localhost:%d", *s.Port), c)
}(s)
}
if s.TLS != nil && !securePorts[s.TLS.Port] {
securePorts[s.TLS.Port] = true
go func(s SiteConfig) {
err <- http.ListenAndServeTLS(
fmt.Sprintf("localhost:%d", s.TLS.Port),
s.TLS.CertPath,
s.TLS.KeyPath,
c,
)
}(s)
}
}
for {
return <- err
}
return nil
}
func (c Config) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
for i := range c.Sites {
if c.Sites[i].MatchesRequest(r) {
c.Sites[i].Handle(rw, r)
return
}
}
http.NotFound(rw, r)
}
func (s SiteConfig) MatchesRequest(r *http.Request) bool {
sh := *s.Host
if strings.HasPrefix(sh, "*") {
return strings.HasSuffix(r.Host, sh[1:])
}
return sh == r.Host
}
func (s SiteConfig) sessionStore() sessions.Store {
keys := [][]byte{}
for _, k := range s.CookieKeys {
key, err := base64.StdEncoding.DecodeString(k.AuthenticateBase64)
if err != nil {
panic(err)
}
if len(key) != 32 {
log.Panicf("AuthenticateBase64 key %s must be 32 bytes; suggest %s", k.AuthenticateBase64, makeAuthKey())
}
keys = append(keys, key)
key, err = base64.StdEncoding.DecodeString(k.EncryptBase64)
if err != nil {
panic(err)
}
if len(key) != 32 {
log.Panicf("EncryptBase64 key %s must be 32 bytes, suggest %s", k.EncryptBase64, makeAuthKey())
}
keys = append(keys, key)
}
return sessions.NewStore(keys...)
}
func (s SiteConfig) Handle(rw http.ResponseWriter, r *http.Request) {
dataDir := strings.Replace(*s.DataDir, "${HOST}", r.Host, -1)
router := server.Site{
PathToData: dataDir,
Css: []byte{},
DefaultPage: *s.DefaultPage,
DefaultPassword: *s.Lock,
Debounce: *s.DebounceSave,
Diary: *s.Diary,
SessionStore: s.sessionStore(),
SecretCode: *s.AccessCode,
AllowInsecure: *s.AllowInsecureMarkup,
Fileuploads: *s.MaxFileUploadMb > 0,
MaxUploadSize: *s.MaxFileUploadMb,
Logger: lumber.NewConsoleLogger(server.LogLevel),
MaxDocumentSize: *s.MaxDocumentLength,
}.Router()
router.ServeHTTP(rw, r)
}