frontend,api: refactor static router
This commit is contained in:
parent
c29b3a7a25
commit
6d00a8e3aa
@ -1,41 +1,81 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"html/template"
|
"strings"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"mime"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"mime"
|
||||||
"path"
|
"path"
|
||||||
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func redirectLogin(w http.ResponseWriter, r *http.Request) {
|
func redirectLogin(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Redirect(w, r, os.Getenv("ORIGIN")+"/login", 301)
|
http.Redirect(w, r, os.Getenv("ORIGIN")+"/login", 301)
|
||||||
}
|
}
|
||||||
|
|
||||||
type staticAssetPlugs struct {
|
type staticPlugs struct {
|
||||||
Origin string
|
|
||||||
}
|
|
||||||
|
|
||||||
type staticHtmlPlugs struct {
|
|
||||||
Origin string
|
Origin string
|
||||||
CdnPrefix string
|
CdnPrefix string
|
||||||
Footer template.HTML
|
Footer string
|
||||||
|
}
|
||||||
|
|
||||||
|
var asset map[string][]byte = make(map[string][]byte)
|
||||||
|
var contentType map[string]string = make(map[string]string)
|
||||||
|
var footer string
|
||||||
|
var compress bool
|
||||||
|
|
||||||
|
func fileDetemplate(f string) ([]byte, error) {
|
||||||
|
contents, err := ioutil.ReadFile(f)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot read file %s: %v", f, err)
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
x := string(contents)
|
||||||
|
x = strings.Replace(x, "[[[.Origin]]]", os.Getenv("ORIGIN"), -1)
|
||||||
|
x = strings.Replace(x, "[[[.CdnPrefix]]]", os.Getenv("CDN_PREFIX"), -1)
|
||||||
|
x = strings.Replace(x, "[[[.Footer]]]", footer, -1)
|
||||||
|
|
||||||
|
return []byte(x), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func footerInit() error {
|
||||||
|
contents, err := fileDetemplate(os.Getenv("STATIC") + "/footer.html")
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot init footer: %v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
footer = string(contents)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func fileLoad(f string) ([]byte, error) {
|
||||||
|
b, err := fileDetemplate(f)
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("cannot load file %s: %v", f, err)
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !compress {
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return gzipStatic(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
func staticRouterInit(router *mux.Router) error {
|
func staticRouterInit(router *mux.Router) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
subdir := pathStrip(os.Getenv("ORIGIN"))
|
subdir := pathStrip(os.Getenv("ORIGIN"))
|
||||||
|
|
||||||
asset := make(map[string][]byte)
|
if err = footerInit(); err != nil {
|
||||||
gzippedAsset := make(map[string][]byte)
|
logger.Errorf("error initialising static router: %v", err)
|
||||||
|
return err
|
||||||
for _, dir := range []string{"js", "css", "images"} {
|
}
|
||||||
sl := string(os.PathSeparator)
|
|
||||||
dir = sl + dir
|
|
||||||
|
|
||||||
|
for _, dir := range []string{"/js", "/css", "/images"} {
|
||||||
files, err := ioutil.ReadDir(os.Getenv("STATIC") + dir)
|
files, err := ioutil.ReadDir(os.Getenv("STATIC") + dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read directory %s%s: %v", os.Getenv("STATIC"), dir, err)
|
logger.Errorf("cannot read directory %s%s: %v", os.Getenv("STATIC"), dir, err)
|
||||||
@ -43,108 +83,47 @@ func staticRouterInit(router *mux.Router) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
p := dir + sl + file.Name()
|
f := dir + "/" + file.Name()
|
||||||
|
asset[subdir+f], err = fileLoad(os.Getenv("STATIC") + f)
|
||||||
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + p)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), p, err)
|
logger.Errorf("cannot detemplate %s%s: %v", os.Getenv("STATIC"), f, err)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix := ""
|
|
||||||
if dir == "/js" {
|
|
||||||
prefix = `window.commento = {origin: "` + os.Getenv("ORIGIN") + `", cdn: "` + os.Getenv("CDN_PREFIX") + `"};
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
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{
|
pages := []string{
|
||||||
"login",
|
"/login",
|
||||||
"forgot",
|
"/forgot",
|
||||||
"reset-password",
|
"/reset-password",
|
||||||
"signup",
|
"/signup",
|
||||||
"confirm-email",
|
"/confirm-email",
|
||||||
"dashboard",
|
"/dashboard",
|
||||||
"logout",
|
"/logout",
|
||||||
}
|
|
||||||
|
|
||||||
html := make(map[string]string)
|
|
||||||
for _, page := range pages {
|
|
||||||
html[subdir+page] = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, page := range pages {
|
for _, page := range pages {
|
||||||
sl := string(os.PathSeparator)
|
f := page + ".html"
|
||||||
page = sl + page
|
asset[subdir+page], err = fileLoad(os.Getenv("STATIC") + f)
|
||||||
file := page + ".html"
|
|
||||||
|
|
||||||
contents, err := ioutil.ReadFile(os.Getenv("STATIC") + file)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("cannot read file %s%s: %v", os.Getenv("STATIC"), file, err)
|
logger.Errorf("cannot detemplate %s%s: %v", os.Getenv("STATIC"), f, err)
|
||||||
return 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
|
for p, _ := range(asset) {
|
||||||
t.Execute(&buf, &staticHtmlPlugs{
|
if path.Ext(p) != "" {
|
||||||
Origin: os.Getenv("ORIGIN"),
|
contentType[p] = mime.TypeByExtension(path.Ext(p))
|
||||||
CdnPrefix: os.Getenv("CDN_PREFIX"),
|
|
||||||
Footer: template.HTML(string(footer)),
|
|
||||||
})
|
|
||||||
|
|
||||||
result = buf.String()
|
|
||||||
if result == html[subdir+page] {
|
|
||||||
break
|
|
||||||
} else {
|
} else {
|
||||||
html[subdir+page] = result
|
contentType[p] = mime.TypeByExtension("html")
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, page := range pages {
|
router.HandleFunc(p, func(w http.ResponseWriter, r *http.Request) {
|
||||||
router.HandleFunc("/"+page, func(w http.ResponseWriter, r *http.Request) {
|
w.Header().Set("Content-Type", contentType[r.URL.Path])
|
||||||
fmt.Fprint(w, html[r.URL.Path])
|
if compress {
|
||||||
|
w.Header().Set("Content-Encoding", "gzip")
|
||||||
|
}
|
||||||
|
w.Write(asset[r.URL.Path])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,28 +26,33 @@ const jsCompileMap = {
|
|||||||
"js/highlight.js": ["node_modules/highlightjs/highlight.pack.min.js"],
|
"js/highlight.js": ["node_modules/highlightjs/highlight.pack.min.js"],
|
||||||
"js/chartist.js": ["node_modules/chartist/dist/chartist.min.js"],
|
"js/chartist.js": ["node_modules/chartist/dist/chartist.min.js"],
|
||||||
"js/login.js": [
|
"js/login.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/http.js",
|
"js/http.js",
|
||||||
"js/auth-common.js",
|
"js/auth-common.js",
|
||||||
"js/login.js"
|
"js/login.js"
|
||||||
],
|
],
|
||||||
"js/forgot.js": [
|
"js/forgot.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/http.js",
|
"js/http.js",
|
||||||
"js/forgot.js"
|
"js/forgot.js"
|
||||||
],
|
],
|
||||||
"js/reset.js": [
|
"js/reset.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/http.js",
|
"js/http.js",
|
||||||
"js/reset.js"
|
"js/reset.js"
|
||||||
],
|
],
|
||||||
"js/signup.js": [
|
"js/signup.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/http.js",
|
"js/http.js",
|
||||||
"js/auth-common.js",
|
"js/auth-common.js",
|
||||||
"js/signup.js"
|
"js/signup.js"
|
||||||
],
|
],
|
||||||
"js/dashboard.js": [
|
"js/dashboard.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/http.js",
|
"js/http.js",
|
||||||
"js/errors.js",
|
"js/errors.js",
|
||||||
@ -63,6 +68,7 @@ const jsCompileMap = {
|
|||||||
"js/dashboard-danger.js",
|
"js/dashboard-danger.js",
|
||||||
],
|
],
|
||||||
"js/logout.js": [
|
"js/logout.js": [
|
||||||
|
"js/constants.js",
|
||||||
"js/utils.js",
|
"js/utils.js",
|
||||||
"js/logout.js"
|
"js/logout.js"
|
||||||
],
|
],
|
||||||
|
@ -65,8 +65,8 @@
|
|||||||
var ID_FOOTER = "commento-footer";
|
var ID_FOOTER = "commento-footer";
|
||||||
|
|
||||||
|
|
||||||
var origin = global.origin;
|
var origin = "[[[.Origin]]]";
|
||||||
var cdn = global.cdn;
|
var cdn = "[[[.CdnPrefix]]]";
|
||||||
var root = null;
|
var root = null;
|
||||||
var cssOverride;
|
var cssOverride;
|
||||||
var autoInit;
|
var autoInit;
|
||||||
|
13
frontend/js/constants.js
Normal file
13
frontend/js/constants.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
(function (global, document) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(document);
|
||||||
|
|
||||||
|
if (window.commento === undefined) {
|
||||||
|
window.commento = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.commento.origin = "[[[.Origin]]]";
|
||||||
|
window.commento.cdn = "[[[.CdnPrefix]]]";
|
||||||
|
|
||||||
|
} (window, document));
|
Loading…
Reference in New Issue
Block a user