aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Riedstra <mitch@riedstra.dev>2021-10-24 15:57:32 -0400
committerMitchell Riedstra <mitch@riedstra.dev>2021-10-24 16:01:05 -0400
commit235b8f871fdfa35f9595268d194d28a3de655ec0 (patch)
tree46f562fddffd38ee10d5e3d858dd80c088879689
parente0d4a3e50921dc07e23ef9aa107bdc78b3adf176 (diff)
downloadgo-website-0.0.16.tar.gz
go-website-0.0.16.tar.xz
Unix sockets for redis. Page use FS interface. Clear redis func.v0.0.16
Additionally, Funcs can be passed in.
-rw-r--r--cmd/server/app.go19
-rw-r--r--cmd/server/handlers.go9
-rw-r--r--cmd/server/main.go11
-rw-r--r--example-site/reIndex.md2
-rw-r--r--page/checkup.go7
-rw-r--r--page/index.go7
-rw-r--r--page/page.go29
-rw-r--r--rediscache/main.go23
8 files changed, 88 insertions, 19 deletions
diff --git a/cmd/server/app.go b/cmd/server/app.go
index c4992ae..4f62a09 100644
--- a/cmd/server/app.go
+++ b/cmd/server/app.go
@@ -2,6 +2,7 @@ package main
import (
"fmt"
+ "log"
"os"
"github.com/gomodule/redigo/redis"
@@ -72,3 +73,21 @@ func loadConf(fn string) (*App, error) {
return app, nil
}
+
+// ClearRedis is a little helper function that allows us to easily clear
+// the redis cache at runtime.
+func (a *App) ClearRedis() error {
+ if a.redisPool == nil {
+ return nil
+ }
+
+ client := a.redisPool.Get()
+ defer client.Close()
+
+ _, err := client.Do("DEL", a.RedisKey)
+ if err != nil {
+ log.Println("Encountered error clearing redis cache: ", err)
+ }
+
+ return fmt.Errorf("clearing redis: %w", err)
+}
diff --git a/cmd/server/handlers.go b/cmd/server/handlers.go
index 61bb623..205d462 100644
--- a/cmd/server/handlers.go
+++ b/cmd/server/handlers.go
@@ -14,13 +14,18 @@ func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
rtr := mux.NewRouter()
rtr.HandleFunc(a.ReIndexPath, a.RebuildIndexHandler)
rtr.PathPrefix("/static/").Handler(a.StaticHandler())
- rtr.PathPrefix(fmt.Sprintf("/%s/{tag}", a.FeedPrefix)).HandlerFunc(
- a.FeedHandler)
if a.redisPool != nil {
+ rtr.PathPrefix(fmt.Sprintf("/%s/{tag}", a.FeedPrefix)).Handler(
+ rediscache.HandleWithParams(a.redisPool, a.RedisKey,
+ http.HandlerFunc(a.FeedHandler)))
+
rtr.PathPrefix("/").Handler(rediscache.Handle(
a.redisPool, a.RedisKey, http.HandlerFunc(a.PageHandler)))
} else {
+ rtr.PathPrefix(fmt.Sprintf("/%s/{tag}", a.FeedPrefix)).HandlerFunc(
+ a.FeedHandler)
+
rtr.PathPrefix("/").Handler(http.HandlerFunc(a.PageHandler))
}
diff --git a/cmd/server/main.go b/cmd/server/main.go
index 21f7031..912cba0 100644
--- a/cmd/server/main.go
+++ b/cmd/server/main.go
@@ -6,6 +6,8 @@ import (
"log"
"net/http"
"os"
+ "strings"
+ "text/template"
"time"
"github.com/gomodule/redigo/redis"
@@ -73,6 +75,11 @@ func main() { //nolint:funlen
MaxActive: 12000, //nolint:gomnd
Dial: func() (redis.Conn, error) {
c, err := redis.Dial("tcp", *redisAddr)
+
+ if strings.HasPrefix(*redisAddr, "unix:") {
+ c, err = redis.Dial("unix", strings.TrimPrefix(*redisAddr, "unix:"))
+ }
+
if err != nil {
log.Println("Redis dial error: ", err)
}
@@ -87,6 +94,10 @@ func main() { //nolint:funlen
os.Stderr.Write(b)
}
+ page.Funcs = template.FuncMap{
+ "ClearRedis": app.ClearRedis,
+ }
+
srv := &http.Server{
Handler: app,
Addr: *listen,
diff --git a/example-site/reIndex.md b/example-site/reIndex.md
index 4519dc5..12c608a 100644
--- a/example-site/reIndex.md
+++ b/example-site/reIndex.md
@@ -6,6 +6,8 @@ description: >
# {{.Title}}
+{{.ClearRedis}}
+
this is the reindex page
{{if .Vars.IndexError}}
diff --git a/page/checkup.go b/page/checkup.go
index 9f721b7..6c3664f 100644
--- a/page/checkup.go
+++ b/page/checkup.go
@@ -2,8 +2,7 @@ package page
import (
"fmt"
- "os"
- "path/filepath"
+ "io/fs"
"reflect"
"strings"
)
@@ -15,8 +14,8 @@ func (p *Page) Checkup() (map[string]PageList, error) {
out := make(map[string]PageList)
- _ = filepath.Walk(filepath.Dir("."),
- func(path string, info os.FileInfo, err error) error {
+ _ = fs.WalkDir(FileSystem, ".",
+ func(path string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
diff --git a/page/index.go b/page/index.go
index 425bf04..00cab4b 100644
--- a/page/index.go
+++ b/page/index.go
@@ -1,8 +1,7 @@
package page
import (
- "os"
- "path/filepath"
+ "io/fs"
"strings"
"sync"
"time"
@@ -41,8 +40,8 @@ func (p *Page) Index() (map[string]PageList, error) {
out := make(map[string]PageList)
- _ = filepath.Walk(filepath.Dir("."),
- func(path string, info os.FileInfo, err error) error {
+ _ = fs.WalkDir(FileSystem, ".",
+ func(path string, info fs.DirEntry, err error) error {
if err != nil {
return err
}
diff --git a/page/page.go b/page/page.go
index fa4ce6c..b2cc3e1 100644
--- a/page/page.go
+++ b/page/page.go
@@ -6,6 +6,8 @@
// markdown, first executed as part of the text/template then rendered by
// blackfriday.
//
+// This package is designed to only be run with ***TRUSTED INPUT***
+//
// Usage:
//
// import (
@@ -28,6 +30,7 @@ import (
"errors"
"fmt"
"io"
+ "io/fs"
"log"
"os"
"path/filepath"
@@ -61,10 +64,18 @@ type Page struct {
// .Global care must be taken when utilizing this functionality.
var Global interface{}
+// Funcs accessible to the templates.
+var Funcs template.FuncMap
+
// CacheIndex determines whether or not the index will be cached in memory
// or rebuilt on each call.
var CacheIndex = true
+// FileSystem can be replaced with anything that implements the fs.FS interface
+// and the website should be able to continue working with a different
+// backend.
+var FileSystem = os.DirFS(".")
+
// BaseTemplate can be adjusted to change the base template used in rendering.
var BaseTemplate = "inc/base.html"
@@ -108,11 +119,18 @@ func (p *Page) Render(wr io.Writer) error {
return err
}
- t, err := template.ParseFiles(BaseTemplate)
+ templateContent, err := fs.ReadFile(FileSystem, BaseTemplate)
if err != nil {
- return fmt.Errorf("rendering: %w", err)
+ return fmt.Errorf("reading base template: %w", err)
}
+ t, err := template.New("baseTemplate").Funcs(Funcs).Parse(string(templateContent))
+ if err != nil {
+ return fmt.Errorf("parsing: %w", err)
+ }
+
+ t = t.Funcs(Funcs)
+
return t.Execute(wr, p)
}
@@ -121,7 +139,7 @@ func (p *Page) Read() error {
yamlBuf := bytes.NewBuffer(nil)
markdownBuf := bytes.NewBuffer(nil)
- fh, err := os.Open(p.path + Suffix)
+ fh, err := FileSystem.Open(p.path + Suffix)
if err != nil {
return fmt.Errorf("opening markdown: %w", err)
}
@@ -171,11 +189,12 @@ func (p *Page) Read() error {
}
// RenderBody renders and executes a template from the body of the
-// markdown file, then runs it through the markdown parser.
+// markdown file, then runs it through the markdown parser. Typically
+// this is called in the base template.
func (p *Page) RenderBody() (string, error) {
buf := &bytes.Buffer{}
- t, err := template.New("Body").Parse(string(p.markdown))
+ t, err := template.New("Body").Funcs(Funcs).Parse(string(p.markdown))
if err != nil {
return "", fmt.Errorf("render body: %w", err)
}
diff --git a/rediscache/main.go b/rediscache/main.go
index 7ae3d4d..04ca622 100644
--- a/rediscache/main.go
+++ b/rediscache/main.go
@@ -54,16 +54,31 @@ func (rw *redisHTTPResponseWriter) WriteData() {
rw.Data = rw.buf.Bytes()
}
-// Simple function that will cache the response for given handler in redis
-// and instead of responding with the result from the handler it will
+// HandleWithParams is the same as Handle but caches for the GET params
+// rather than discarding them.
+func HandleWithParams(pool *redis.Pool, key string, next http.Handler) http.Handler {
+ return handle(pool, key, true, next)
+}
+
+// Handle is a Simple function that will cache the response for given handler in
+// redis and instead of responding with the result from the handler it will
// simply dump the contents of the redis key if it exists.
func Handle(pool *redis.Pool, key string, next http.Handler) http.Handler {
+ return handle(pool, key, false, next)
+}
+
+func handle(pool *redis.Pool, key string, params bool, next http.Handler) http.Handler { //nolint:funlen
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
client := pool.Get()
defer client.Close()
+ subkey := r.URL.Path
+ if params {
+ subkey = r.URL.Path + "?" + r.URL.RawQuery
+ }
+
content:
- data, err := client.Do("HGET", key, r.URL.Path)
+ data, err := client.Do("HGET", key, subkey)
if err != nil {
// Assume something bad has happened with redis, we're
// just going to log this and then pass through the
@@ -83,7 +98,7 @@ func Handle(pool *redis.Pool, key string, next http.Handler) http.Handler {
return
}
- _, err = client.Do("HSET", key, r.URL.Path, b)
+ _, err = client.Do("HSET", key, subkey, b)
if err != nil {
Logger.Println("ERROR: during set: ", err)