diff options
-rw-r--r-- | cache.go | 58 | ||||
-rw-r--r-- | http.go | 13 |
2 files changed, 69 insertions, 2 deletions
diff --git a/cache.go b/cache.go new file mode 100644 index 0000000..88d5dba --- /dev/null +++ b/cache.go @@ -0,0 +1,58 @@ +package main + +import ( + "io/ioutil" + "log" + "sync" + "time" +) + +// Holds the cached responses +type page struct { + raw []byte + expires time.Time +} + +// Wraps the page cache map with a rwlock +type cacheWrapper struct { + sync.RWMutex + pages map[string]*page +} + +// The actual page/response cache +var cache = &cacheWrapper{ + pages: make(map[string]*page), +} + +func bapCache(requestPath string) { + cache.RLock() + if cache.pages[requestPath] == nil { + cache.RUnlock() + cacheIndex() + return + } + + expires := cache.pages[requestPath].expires + cache.RUnlock() + + if time.Now().After(expires) { + cacheIndex() + } +} + +// Pulls the index page from disk and places it into the cache. +// etag is an fnv32 hash of the raw file bytes, truncated if necessary. +func cacheIndex() { + bytes, err := ioutil.ReadFile("web/index.txt") + if err != nil { + log.Printf("Could not read index page: %s", err.Error()) + bytes = []byte("tilde.institute informational API") + } + + cache.Lock() + cache.pages["/"] = &page{ + raw: bytes, + expires: time.Now().Add(5 * time.Minute), + } + cache.Unlock() +} diff --git a/http.go b/http.go index ab6050f..93b6d0c 100644 --- a/http.go +++ b/http.go @@ -4,6 +4,7 @@ import ( "errors" "net/http" "strings" + "time" "git.tilde.institute/tilde/api/internal/endpoints" ) @@ -77,8 +78,16 @@ func routingHop(r *http.Request) string { // Yeets the index/summary page to the user func indexHandler(w http.ResponseWriter, r *http.Request) { - w.Header().Add("Content-Type", mimePlain) - out := []byte("This is the tilde.institute informational API") + bapCache("/") + cache.RLock() + defer cache.RUnlock() + + out := cache.pages["/"].raw + expires := cache.pages["/"].expires + + w.Header().Set("Content-Type", mimePlain) + w.Header().Set("Expires", expires.Format(time.RFC1123)) + _, err := w.Write(out) if err != nil { errHTTP(w, r, err, http.StatusInternalServerError) |