aboutsummaryrefslogtreecommitdiff
path: root/cmd/server/handlers.go
blob: 49f203958e8d80e753e828f91cdf4f8d3208fd7c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main

import (
	"net/http"
	"path/filepath"
	"strings"
	"fmt"

	"riedstra.dev/mitch/go-website/mapcache"
	"riedstra.dev/mitch/go-website/page"
	"riedstra.dev/mitch/go-website/rediscache"
)

func (a *App) Handler() http.Handler {
	mux := http.NewServeMux()

	type route struct {
		path string
		handler http.Handler
	}

	routes := []route{
		{a.ReIndexPath, a.RebuildIndexHandler()},
		{"/static/", a.StaticHandler()},
	}
	cacheableRoutes := []route{
		{a.FeedPrefix, http.StripPrefix(a.FeedPrefix, a.FeedHandler())},
		{"/",          a.PageHandler()},
	}

	for _, route := range routes {
		mux.Handle(route.path, route.handler)
	}

	if a.cache == nil && a.RedisKey != "" {
		a.cache = mapcache.New()
	}

	var cacheHandler func(http.Handler) http.Handler = nil
	switch {
	case a.mapCache:
		cacheHandler = a.cache.Handle
	case a.redisPool != nil:
		cacheHandler = func(h http.Handler) http.Handler {
			return rediscache.Handle(a.redisPool, a.RedisKey, h)
		}
	default:
		// No caching middleware
		cacheHandler = func(h http.Handler) http.Handler {
			return h
		}
	}

	if cacheHandler == nil {
		panic("cacheHandler cannot be nil")
	}

	for _, r := range cacheableRoutes {
		fmt.Printf("Calling mux.Handle(r.path(%s), cacheHandler(r.handler(%v)))\n",
			r.path, r.handler)
		mux.Handle(r.path, cacheHandler(r.handler))
	}

	return mux
}

func (a *App) PageHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		u := page.GetURLPath(r)

		// Render nothing inside of the template directory
		if strings.HasPrefix(u[1:], filepath.Clean(page.TemplateDirectory)) {
			return
		}

		u = filepath.Join(".", u)

		page.RenderWithVars(w, r, u, map[string]interface{}{})
	})
}

func (a *App) RebuildIndexHandler() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		u := page.GetPagePath(r)

		p := page.NewPage("index")
		err := p.RebuildIndex()

		page.RenderWithVars(w, r, u, map[string]interface{}{
			"IndexError": err,
		})
	})
}

// StaticHandler simply returns a HTTP handler that looks at the current
// directory and exposes `static` via HTTP `/static`.
func (a *App) StaticHandler() http.Handler {
	return http.StripPrefix("/static/", http.FileServer(http.Dir(a.StaticDirectory)))
}