Browse Source

Upgrade resources & bootstrap library

Vova Tkach 5 years ago
parent
commit
5a4aee44cf

+ 15 - 15
assets/assets.go

@@ -7,19 +7,19 @@ import (
 )
 
 func PopulateResources(res *resource.Resource) {
-	res.Add(consts.AssetsCpImgLoadGif, "image/gif", CpImgLoadGif)
-	res.Add(consts.AssetsCpCodeMirrorCss, "text/css", CpCodeMirrorCss)
-	res.Add(consts.AssetsCpCodeMirrorJs, "application/javascript; charset=utf-8", CpCodeMirrorJs)
-	res.Add(consts.AssetsCpStylesCss, "text/css", CpStylesCss)
-	res.Add(consts.AssetsCpWysiwygPellCss, "text/css", CpWysiwygPellCss)
-	res.Add(consts.AssetsCpWysiwygPellJs, "application/javascript; charset=utf-8", CpWysiwygPellJs)
-	res.Add(consts.AssetsLightGalleryCss, "text/css", LightGalleryCss)
-	res.Add(consts.AssetsLightGalleryJs, "application/javascript; charset=utf-8", LightGalleryJs)
-	res.Add(consts.AssetsSysBgPng, "image/png", SysBgPng)
-	res.Add(consts.AssetsSysFaveIco, "image/x-icon", SysFaveIco)
-	res.Add(consts.AssetsSysLogoPng, "image/png", SysLogoPng)
-	res.Add(consts.AssetsSysLogoSvg, "image/svg+xml", SysLogoSvg)
-	res.Add(consts.AssetsSysStylesCss, "text/css", SysStylesCss)
-	res.Add(consts.AssetsCpScriptsJs, "application/javascript; charset=utf-8", CpScriptsJs)
-	res.Add(consts.AssetsSysPlaceholderPng, "image/png", SysPlaceholderPng)
+	res.Add(consts.AssetsCpImgLoadGif, "image/gif", CpImgLoadGif, 1)
+	res.Add(consts.AssetsCpCodeMirrorCss, "text/css", CpCodeMirrorCss, 1)
+	res.Add(consts.AssetsCpCodeMirrorJs, "application/javascript; charset=utf-8", CpCodeMirrorJs, 1)
+	res.Add(consts.AssetsCpStylesCss, "text/css", CpStylesCss, 1)
+	res.Add(consts.AssetsCpWysiwygPellCss, "text/css", CpWysiwygPellCss, 1)
+	res.Add(consts.AssetsCpWysiwygPellJs, "application/javascript; charset=utf-8", CpWysiwygPellJs, 1)
+	res.Add(consts.AssetsLightGalleryCss, "text/css", LightGalleryCss, 1)
+	res.Add(consts.AssetsLightGalleryJs, "application/javascript; charset=utf-8", LightGalleryJs, 1)
+	res.Add(consts.AssetsSysBgPng, "image/png", SysBgPng, 1)
+	res.Add(consts.AssetsSysFaveIco, "image/x-icon", SysFaveIco, 1)
+	res.Add(consts.AssetsSysLogoPng, "image/png", SysLogoPng, 1)
+	res.Add(consts.AssetsSysLogoSvg, "image/svg+xml", SysLogoSvg, 1)
+	res.Add(consts.AssetsSysStylesCss, "text/css", SysStylesCss, 1)
+	res.Add(consts.AssetsCpScriptsJs, "application/javascript; charset=utf-8", CpScriptsJs, 1)
+	res.Add(consts.AssetsSysPlaceholderPng, "image/png", SysPlaceholderPng, 1)
 }

+ 2 - 2
go.mod

@@ -3,8 +3,8 @@ module golang-fave
 require (
 	github.com/disintegration/imaging v1.6.1
 	github.com/go-sql-driver/mysql v1.4.1
-	github.com/vladimirok5959/golang-server-bootstrap v1.1.1
-	github.com/vladimirok5959/golang-server-resources v1.0.4
+	github.com/vladimirok5959/golang-server-bootstrap v1.1.2
+	github.com/vladimirok5959/golang-server-resources v1.0.6
 	github.com/vladimirok5959/golang-server-sessions v1.0.6
 	github.com/vladimirok5959/golang-server-static v1.0.2
 	google.golang.org/appengine v1.4.0 // indirect

+ 4 - 4
go.sum

@@ -5,10 +5,10 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/vladimirok5959/golang-ctrlc v1.0.2 h1:TVMWJv0WSdJqIzfnQ/Lhr9HmQ+i6H6kD6kIn8X+BNFs=
 github.com/vladimirok5959/golang-ctrlc v1.0.2/go.mod h1:fIz52p0IMNedUfGBoT82xKAuFGfFMeQhYp+ne0FIKwU=
-github.com/vladimirok5959/golang-server-bootstrap v1.1.1 h1:wELSsO0Jr7g/31qXCtLK2EM9pAa4FiKOgDBpUWL5d/Y=
-github.com/vladimirok5959/golang-server-bootstrap v1.1.1/go.mod h1:xDrCyDXa5+xdzptoPSfn7JOhLO1+Q95xTPlrdovyBSg=
-github.com/vladimirok5959/golang-server-resources v1.0.4 h1:myqowOUgF7DPdXWbNGBqxVsn9MfAi+FTHr8DvWkJFgM=
-github.com/vladimirok5959/golang-server-resources v1.0.4/go.mod h1:TQ9jCCEpRE2ThB/JgxVE8k4yu3PY43qq339vsWLohSQ=
+github.com/vladimirok5959/golang-server-bootstrap v1.1.2 h1:ctGpPR3+hKehMPOL45kiM211G0rivAnoThJQs/nvwis=
+github.com/vladimirok5959/golang-server-bootstrap v1.1.2/go.mod h1:xDrCyDXa5+xdzptoPSfn7JOhLO1+Q95xTPlrdovyBSg=
+github.com/vladimirok5959/golang-server-resources v1.0.6 h1:VFbnyo32RRL/ZNOvLpWgRHyFzW6bMX2baASJ3ssUqJw=
+github.com/vladimirok5959/golang-server-resources v1.0.6/go.mod h1:TQ9jCCEpRE2ThB/JgxVE8k4yu3PY43qq339vsWLohSQ=
 github.com/vladimirok5959/golang-server-sessions v1.0.6 h1:i5W1hnWZ63B6x3mTvPK8gsy74E5maQ81142ZlmpKbE4=
 github.com/vladimirok5959/golang-server-sessions v1.0.6/go.mod h1:H99PB5Va7fw+Iljgne/f4ISsjg+V18Gq+9cNp+R6gaQ=
 github.com/vladimirok5959/golang-server-static v1.0.2 h1:pNR+vy+z2g73ETyx+50WxM4x2vqku3J1QCcRp7DnORo=

+ 3 - 11
main.go

@@ -134,7 +134,6 @@ func main() {
 				r *http.Request,
 				i *resource.OneResource,
 			) {
-				w.Header().Set("Cache-Control", "public, max-age=31536000")
 				if consts.ParamDebug && i.Path == "assets/cp/scripts.js" {
 					w.Write([]byte("window.fave_debug=true;"))
 				}
@@ -315,16 +314,9 @@ func ServeTemplateFile(
 	dir string,
 ) bool {
 	if r.URL.Path == "/"+path+file {
-		f, err := os.Open(dir + string(os.PathSeparator) + file)
-		if err == nil {
-			defer f.Close()
-			st, err := os.Stat(dir + string(os.PathSeparator) + file)
-			if err == nil {
-				if !st.Mode().IsDir() {
-					http.ServeFile(w, r, dir+string(os.PathSeparator)+file)
-					return true
-				}
-			}
+		if utils.IsRegularFileExists(dir + string(os.PathSeparator) + file) {
+			http.ServeFile(w, r, dir+string(os.PathSeparator)+file)
+			return true
 		}
 	}
 	return false

+ 11 - 0
utils/utils.go

@@ -35,6 +35,17 @@ func IsFileExists(filename string) bool {
 	return false
 }
 
+func IsRegularFileExists(filename string) bool {
+	if st, err := os.Stat(filename); !os.IsNotExist(err) {
+		if err == nil {
+			if !st.Mode().IsDir() {
+				return true
+			}
+		}
+	}
+	return false
+}
+
 func IsDir(filename string) bool {
 	if st, err := os.Stat(filename); !os.IsNotExist(err) {
 		if err == nil {

+ 7 - 0
utils/utils_test.go

@@ -20,10 +20,17 @@ func Expect(t *testing.T, actual, expect interface{}) {
 }
 
 func TestIsFileExists(t *testing.T) {
+	Expect(t, IsFileExists("./../support"), true)
 	Expect(t, IsFileExists("./../support/some-file.txt"), true)
 	Expect(t, IsFileExists("./../support/no-existed-file"), false)
 }
 
+func TestIsRegularFileExists(t *testing.T) {
+	Expect(t, IsRegularFileExists("./../support/some-file.txt"), true)
+	Expect(t, IsRegularFileExists("./../support/no-existed-file"), false)
+	Expect(t, IsRegularFileExists("./../support"), false)
+}
+
 func TestIsDir(t *testing.T) {
 	Expect(t, IsDir("./../support"), true)
 	Expect(t, IsDir("./../support/some-file.txt"), false)

+ 11 - 11
vendor/github.com/vladimirok5959/golang-server-bootstrap/bootstrap/bootstrap.go

@@ -54,16 +54,16 @@ func etag(str string) string {
 	return hex.EncodeToString(hasher.Sum(nil))
 }
 
-func modified(p string, s int, v int64, w *http.ResponseWriter, r *http.Request) bool {
-	(*w).Header().Set("Content-Length", fmt.Sprintf("%d", s))
-	(*w).Header().Set("Cache-Control", "no-cache")
+func modified(p string, s int, v int64, w http.ResponseWriter, r *http.Request) bool {
+	w.Header().Set("Content-Length", fmt.Sprintf("%d", s))
+	w.Header().Set("Cache-Control", "no-cache")
 
 	// Set: ETag
 	ehash := etag(fmt.Sprintf("%s-%d-%d", p, s, v))
-	(*w).Header().Set("ETag", fmt.Sprintf("%s", ehash))
+	w.Header().Set("ETag", fmt.Sprintf("%s", ehash))
 
 	// Set: Last-Modified
-	(*w).Header().Set(
+	w.Header().Set(
 		"Last-Modified",
 		time.Unix(v, 0).In(time.FixedZone("GMT", 0)).Format("Wed, 01 Oct 2006 15:04:05 GMT"),
 	)
@@ -71,7 +71,7 @@ func modified(p string, s int, v int64, w *http.ResponseWriter, r *http.Request)
 	// Check: ETag
 	if cc := r.Header.Get("Cache-Control"); cc != "no-cache" {
 		if inm := r.Header.Get("If-None-Match"); inm == ehash {
-			(*w).WriteHeader(http.StatusNotModified)
+			w.WriteHeader(http.StatusNotModified)
 			return false
 		}
 	}
@@ -81,7 +81,7 @@ func modified(p string, s int, v int64, w *http.ResponseWriter, r *http.Request)
 		if ims := r.Header.Get("If-Modified-Since"); ims != "" {
 			if t, err := time.Parse("Wed, 01 Oct 2006 15:04:05 GMT", ims); err == nil {
 				if time.Unix(v, 0).In(time.FixedZone("GMT", 0)).Unix() <= t.In(time.FixedZone("GMT", 0)).Unix() {
-					(*w).WriteHeader(http.StatusNotModified)
+					w.WriteHeader(http.StatusNotModified)
 					return false
 				}
 			}
@@ -97,28 +97,28 @@ func (this *bootstrap) handler(w http.ResponseWriter, r *http.Request) {
 	}
 	if r.URL.Path == "/"+this.opts.Path+"/bootstrap.css" {
 		w.Header().Set("Content-Type", "text/css")
-		if !modified(r.URL.Path, len(rbc), rbcm, &w, r) {
+		if !modified(r.URL.Path, len(rbc), rbcm, w, r) {
 			return
 		}
 		w.Write(rbc)
 		return
 	} else if r.URL.Path == "/"+this.opts.Path+"/bootstrap.js" {
 		w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
-		if !modified(r.URL.Path, len(rbj), rbjm, &w, r) {
+		if !modified(r.URL.Path, len(rbj), rbjm, w, r) {
 			return
 		}
 		w.Write(rbj)
 		return
 	} else if r.URL.Path == "/"+this.opts.Path+"/jquery.js" {
 		w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
-		if !modified(r.URL.Path, len(rjj), rjjm, &w, r) {
+		if !modified(r.URL.Path, len(rjj), rjjm, w, r) {
 			return
 		}
 		w.Write(rjj)
 		return
 	} else if r.URL.Path == "/"+this.opts.Path+"/popper.js" {
 		w.Header().Set("Content-Type", "application/javascript; charset=utf-8")
-		if !modified(r.URL.Path, len(rpj), rpjm, &w, r) {
+		if !modified(r.URL.Path, len(rpj), rpjm, w, r) {
 			return
 		}
 		w.Write(rpj)

+ 55 - 2
vendor/github.com/vladimirok5959/golang-server-resources/resource/resource.go

@@ -1,13 +1,18 @@
 package resource
 
 import (
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
 	"net/http"
+	"time"
 )
 
 type OneResource struct {
 	Path  string
 	Ctype string
 	Bytes []byte
+	MTime int64
 }
 
 type Resource struct {
@@ -20,7 +25,49 @@ func New() *Resource {
 	return &r
 }
 
-func (this *Resource) Add(path string, ctype string, bytes []byte) {
+func etag(str string) string {
+	hasher := md5.New()
+	hasher.Write([]byte(str))
+	return hex.EncodeToString(hasher.Sum(nil))
+}
+
+func modified(p string, s int, v int64, w http.ResponseWriter, r *http.Request) bool {
+	w.Header().Set("Cache-Control", "no-cache")
+
+	// Set: ETag
+	ehash := etag(fmt.Sprintf("%s-%d-%d", p, s, v))
+	w.Header().Set("ETag", fmt.Sprintf("%s", ehash))
+
+	// Set: Last-Modified
+	w.Header().Set(
+		"Last-Modified",
+		time.Unix(v, 0).In(time.FixedZone("GMT", 0)).Format("Wed, 01 Oct 2006 15:04:05 GMT"),
+	)
+
+	// Check: ETag
+	if cc := r.Header.Get("Cache-Control"); cc != "no-cache" {
+		if inm := r.Header.Get("If-None-Match"); inm == ehash {
+			w.WriteHeader(http.StatusNotModified)
+			return false
+		}
+	}
+
+	// Check: Last-Modified
+	if cc := r.Header.Get("Cache-Control"); cc != "no-cache" {
+		if ims := r.Header.Get("If-Modified-Since"); ims != "" {
+			if t, err := time.Parse("Wed, 01 Oct 2006 15:04:05 GMT", ims); err == nil {
+				if time.Unix(v, 0).In(time.FixedZone("GMT", 0)).Unix() <= t.In(time.FixedZone("GMT", 0)).Unix() {
+					w.WriteHeader(http.StatusNotModified)
+					return false
+				}
+			}
+		}
+	}
+
+	return true
+}
+
+func (this *Resource) Add(path string, ctype string, bytes []byte, mtime int64) {
 	// Do not add if already in resources list
 	if _, ok := this.list[path]; ok == true {
 		return
@@ -31,6 +78,7 @@ func (this *Resource) Add(path string, ctype string, bytes []byte) {
 		Path:  path,
 		Ctype: ctype,
 		Bytes: bytes,
+		MTime: mtime,
 	}
 }
 
@@ -46,13 +94,18 @@ func (this *Resource) Response(w http.ResponseWriter, r *http.Request, before fu
 		return false
 	}
 
+	// Cache headers
+	w.Header().Set("Content-Type", res.Ctype)
+	if !modified(r.URL.Path, len(res.Bytes), res.MTime, w, r) {
+		return true
+	}
+
 	// Call `before` callback
 	if before != nil {
 		before(w, r, &res)
 	}
 
 	// Send resource
-	w.Header().Set("Content-Type", res.Ctype)
 	w.Write(res.Bytes)
 
 	// Call `after` callback

+ 2 - 2
vendor/modules.txt

@@ -4,9 +4,9 @@ github.com/disintegration/imaging
 github.com/go-sql-driver/mysql
 # github.com/vladimirok5959/golang-ctrlc v1.0.2
 github.com/vladimirok5959/golang-ctrlc/ctrlc
-# github.com/vladimirok5959/golang-server-bootstrap v1.1.1
+# github.com/vladimirok5959/golang-server-bootstrap v1.1.2
 github.com/vladimirok5959/golang-server-bootstrap/bootstrap
-# github.com/vladimirok5959/golang-server-resources v1.0.4
+# github.com/vladimirok5959/golang-server-resources v1.0.6
 github.com/vladimirok5959/golang-server-resources/resource
 # github.com/vladimirok5959/golang-server-sessions v1.0.6
 github.com/vladimirok5959/golang-server-sessions/session