commento/api/router_static.go
2018-09-26 03:18:36 -04:00

155 lines
3.4 KiB
Go

package main
import (
"bytes"
"fmt"
"github.com/gorilla/mux"
"html/template"
"io/ioutil"
"mime"
"net/http"
"os"
"path"
)
func redirectLogin(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, os.Getenv("ORIGIN")+"/login", 301)
}
type staticAssetPlugs struct {
Origin string
}
type staticHtmlPlugs struct {
Origin string
CdnPrefix string
Footer template.HTML
}
func staticRouterInit(router *mux.Router) error {
subdir := pathStrip(os.Getenv("ORIGIN"))
asset := make(map[string][]byte)
gzippedAsset := make(map[string][]byte)
for _, dir := range []string{"js", "css", "images"} {
sl := string(os.PathSeparator)
dir = sl + dir
files, err := ioutil.ReadDir(os.Getenv("STATIC") + dir)
if err != nil {
logger.Errorf("cannot read directory %s%s: %v", os.Getenv("STATIC"), dir, err)
return err
}
for _, file := range files {
p := dir + sl + file.Name()
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + p)
if err != nil {
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), p, err)
return err
}
prefix := ""
if dir == "/js" {
prefix = "window.commentoOrigin='" + os.Getenv("ORIGIN") + "';\n"
prefix += "window.commentoCdn='" + os.Getenv("CDN_PREFIX") + "';\n"
}
gzip := (os.Getenv("GZIP_STATIC") == "true")
asset[subdir+p] = []byte(prefix + string(contents))
if gzip {
gzippedAsset[subdir+p], err = gzipStatic(asset[subdir+p])
if err != nil {
logger.Errorf("error gzipping %s: %v", p, err)
return err
}
}
// faster than checking inside the handler
if !gzip {
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path)))
w.Write(asset[r.URL.Path])
})
} else {
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", mime.TypeByExtension(path.Ext(r.URL.Path)))
w.Header().Set("Content-Encoding", "gzip")
w.Write(gzippedAsset[r.URL.Path])
})
}
}
}
footer, err := ioutil.ReadFile(os.Getenv("STATIC") + string(os.PathSeparator) + "footer.html")
if err != nil {
logger.Errorf("cannot read file footer.html: %v", err)
return err
}
pages := []string{
"login",
"forgot",
"reset-password",
"signup",
"confirm-email",
"dashboard",
"logout",
}
html := make(map[string]string)
for _, page := range pages {
html[subdir+page] = ""
}
for _, page := range pages {
sl := string(os.PathSeparator)
page = sl + page
file := page + ".html"
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + file)
if err != nil {
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), file, err)
return err
}
result := string(contents)
for {
t, err := template.New(page).Delims("[[[", "]]]").Parse(result)
if err != nil {
logger.Errorf("cannot parse %s%s template: %v", os.Getenv("STATIC"), file, err)
return err
}
var buf bytes.Buffer
t.Execute(&buf, &staticHtmlPlugs{
Origin: os.Getenv("ORIGIN"),
CdnPrefix: os.Getenv("CDN_PREFIX"),
Footer: template.HTML(string(footer)),
})
result = buf.String()
if result == html[subdir+page] {
break
} else {
html[subdir+page] = result
continue
}
}
}
for _, page := range pages {
router.HandleFunc("/"+page, func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, html[r.URL.Path])
})
}
router.HandleFunc("/", redirectLogin)
return nil
}