2018-05-27 14:51:33 +03:00
|
|
|
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)
|
|
|
|
}
|
2018-08-22 05:36:24 +03:00
|
|
|
return sessions.NewStore(keys...)
|
2018-05-27 14:51:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
}
|