caching improvements

Signed-off-by: ari melody <ari@arimelody.me>
This commit is contained in:
ari melody 2024-04-17 17:08:53 +01:00
parent c5a2491627
commit 0b401c058a
4 changed files with 94 additions and 55 deletions

71
main.go
View file

@ -19,6 +19,7 @@ import (
) )
const PORT int = 8080 const PORT int = 8080
var LAST_MODIFIED = time.Now()
var mime_types = map[string]string{ var mime_types = map[string]string{
"css": "text/css; charset=utf-8", "css": "text/css; charset=utf-8",
@ -73,6 +74,10 @@ func handle_request(writer http.ResponseWriter, req *http.Request) {
// } // }
// } // }
writer.Header().Set("Server", "arimelody.me")
writer.Header().Set("Cache-Control", "max-age=86400")
writer.Header().Set("Last-Modified", LAST_MODIFIED.Format(http.TimeFormat))
code := func(writer http.ResponseWriter, req *http.Request) int { code := func(writer http.ResponseWriter, req *http.Request) int {
// var root *template.Template // var root *template.Template
// if hx_request { // if hx_request {
@ -84,19 +89,19 @@ func handle_request(writer http.ResponseWriter, req *http.Request) {
var root = template.Must(base_template.Clone()) var root = template.Must(base_template.Clone())
if req.URL.Path == "/" { if req.URL.Path == "/" {
return index_handler(writer, root) return handle_index(writer, req, root)
} }
if uri == "/music" || uri == "/music/" { if uri == "/music" || uri == "/music/" {
return music_directory_handler(writer, root) return handle_music(writer, req, root)
} }
if strings.HasPrefix(uri, "/music/") { if strings.HasPrefix(uri, "/music/") {
return music_gateway_handler(writer, req, root) return handle_music_gateway(writer, req, root)
} }
if strings.HasPrefix(uri, "/admin") { if strings.HasPrefix(uri, "/admin") {
return admin_handler(writer, req, root) return handle_admin(writer, req, root)
} }
if strings.HasPrefix(uri, "/api") { if strings.HasPrefix(uri, "/api") {
@ -109,7 +114,12 @@ func handle_request(writer http.ResponseWriter, req *http.Request) {
log_request(req, code, start_time) log_request(req, code, start_time)
} }
func index_handler(writer http.ResponseWriter, root *template.Template) int { func handle_index(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if !was_modified(req, LAST_MODIFIED) {
writer.WriteHeader(304)
return 304
}
index_template := template.Must(root.ParseFiles("views/index.html")) index_template := template.Must(root.ParseFiles("views/index.html"))
err := index_template.Execute(writer, nil) err := index_template.Execute(writer, nil)
if err != nil { if err != nil {
@ -119,7 +129,12 @@ func index_handler(writer http.ResponseWriter, root *template.Template) int {
return 200 return 200
} }
func music_directory_handler(writer http.ResponseWriter, root *template.Template) int { func handle_music(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if !was_modified(req, LAST_MODIFIED) {
writer.WriteHeader(304)
return 304
}
music_template := template.Must(root.ParseFiles("views/music.html")) music_template := template.Must(root.ParseFiles("views/music.html"))
music := music.QueryAllMusic() music := music.QueryAllMusic()
err := music_template.Execute(writer, music) err := music_template.Execute(writer, music)
@ -130,7 +145,12 @@ func music_directory_handler(writer http.ResponseWriter, root *template.Template
return 200 return 200
} }
func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int { func handle_music_gateway(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if !was_modified(req, LAST_MODIFIED) {
writer.WriteHeader(304)
return 304
}
id := req.URL.Path[len("/music/"):] id := req.URL.Path[len("/music/"):]
// http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302) // http.Redirect(writer, req, "https://mellodoot.com/music/"+title, 302)
// return // return
@ -147,7 +167,12 @@ func music_gateway_handler(writer http.ResponseWriter, req *http.Request, root *
return 200 return 200
} }
func admin_handler(writer http.ResponseWriter, req *http.Request, root *template.Template) int { func handle_admin(writer http.ResponseWriter, req *http.Request, root *template.Template) int {
if !was_modified(req, LAST_MODIFIED) {
writer.WriteHeader(304)
return 304
}
admin_template := template.Must(root.ParseFiles("views/admin.html")) admin_template := template.Must(root.ParseFiles("views/admin.html"))
err := admin_template.Execute(writer, nil) err := admin_template.Execute(writer, nil)
if err != nil { if err != nil {
@ -166,23 +191,13 @@ func static_handler(writer http.ResponseWriter, req *http.Request, root *templat
return handle_not_found(writer, req, root) return handle_not_found(writer, req, root)
} }
if len(req.Header["If-Modified-Since"]) > 0 && req.Header["If-Modified-Since"][0] != "" { if !was_modified(req, info.ModTime()) {
if_modified_since_time, err := time.Parse(http.TimeFormat, req.Header["If-Modified-Since"][0]) writer.WriteHeader(304)
if err != nil {
http.Error(writer, "400 bad request", http.StatusBadRequest)
return 400
}
if req.Header["If-Modified-Since"][0] == info.ModTime().Format(http.TimeFormat) || if_modified_since_time.After(info.ModTime()) {
writer.WriteHeader(304) // not modified
return 304 return 304
} }
}
// set other nice headers // set Last-Modified to file modification date
writer.Header().Set("Cache-Control", "max-age=86400")
writer.Header().Set("Last-Modified", info.ModTime().Format(http.TimeFormat)) writer.Header().Set("Last-Modified", info.ModTime().Format(http.TimeFormat))
// Last-Modified: <day-name>, <day> <month> <year> <hour>:<minute>:<second> GMT
// Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
// read the file // read the file
body, err := os.ReadFile(filename) body, err := os.ReadFile(filename)
@ -218,6 +233,20 @@ func handle_not_found(writer http.ResponseWriter, req *http.Request, root *templ
return 404 return 404
} }
func was_modified(req *http.Request, last_modified time.Time) bool {
if len(req.Header["If-Modified-Since"]) == 0 || len(req.Header["If-Modified-Since"][0]) == 0 {
return true
}
request_time, err := time.Parse(http.TimeFormat, req.Header["If-Modified-Since"][0])
if err != nil {
return true
}
if request_time.Before(last_modified) {
return true
}
return false
}
func parse_markdown(md []byte) []byte { func parse_markdown(md []byte) []byte {
extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock
p := parser.NewWithExtensions(extensions) p := parser.NewWithExtensions(extensions)

View file

@ -1,22 +1,32 @@
const swap_event = new Event("swap"); const swap_event = new Event("swap");
let caches = {}; let caches = {};
window.lmao = caches;
async function check_cache(url) { async function cached_fetch(url) {
if (caches[url]) { let cached = caches[url];
return caches[url]; console.log("cache: " + cached);
} else {
const res = await fetch(url);
const res = cached === undefined ? await fetch(url) : await fetch(url, {
headers: {
"If-Modified-Since": cached.last_modified
}
});
if (res.status === 304 && cached !== undefined) {
return cached.content;
}
if (res.status !== 200) return; if (res.status !== 200) return;
if (!res.headers.get("content-type").startsWith("text/html")) return; if (!res.headers.get("content-type").startsWith("text/html")) return;
const text = await res.text(); const text = await res.text();
caches[url] = text; if (res.headers.get("last-modified")) {
return text; caches[url] = {
content: text,
last_modified: res.headers.get("last-modified")
} }
} }
return text;
}
async function swap(url, stateful) { async function swap(url, stateful) {
if (typeof url !== 'string') return; if (typeof url !== 'string') return;
@ -29,7 +39,7 @@ async function swap(url, stateful) {
if (stateful && window.location.href.endsWith(url)) return; if (stateful && window.location.href.endsWith(url)) return;
const text = await check_cache(url); const text = await cached_fetch(url);
const content = new DOMParser().parseFromString(text, "text/html"); const content = new DOMParser().parseFromString(text, "text/html");
const stylesheets = [...content.querySelectorAll("link[rel='stylesheet']")]; const stylesheets = [...content.querySelectorAll("link[rel='stylesheet']")];

View file

@ -149,39 +149,39 @@
<div id="web-buttons"> <div id="web-buttons">
<a href="https://arimelody.me"> <a href="https://arimelody.me">
<img src="/img/buttons/ari melody.gif" alt="ari melody web button"> <img src="/img/buttons/ari melody.gif" alt="ari melody web button" loading="lazy">
</a> </a>
<a href="https://supitszaire.com" target="_blank"> <a href="https://supitszaire.com" target="_blank">
<img src="/img/buttons/zaire.gif" alt="zaire web button"> <img src="/img/buttons/zaire.gif" alt="zaire web button" loading="lazy">
</a> </a>
<a href="https://mae.wtf" target="_blank"> <a href="https://mae.wtf" target="_blank">
<img src="/img/buttons/mae.png" alt="vimae web button"> <img src="/img/buttons/mae.png" alt="vimae web button" loading="lazy">
</a> </a>
<a href="https://zvava.org" target="_blank"> <a href="https://zvava.org" target="_blank">
<img src="/img/buttons/zvava.png" alt="zvava web button"> <img src="/img/buttons/zvava.png" alt="zvava web button" loading="lazy">
</a> </a>
<hr> <hr>
<img src="/img/buttons/misc/debian.gif" alt="powered by debian"> <img src="/img/buttons/misc/debian.gif" alt="powered by debian" loading="lazy">
<img src="/img/buttons/misc/girls4notepad.gif" alt="girls 4 notepad"> <img src="/img/buttons/misc/girls4notepad.gif" alt="girls 4 notepad" loading="lazy">
<img src="/img/buttons/misc/gaywebring.gif" alt="this website is GAY"> <img src="/img/buttons/misc/gaywebring.gif" alt="this website is GAY" loading="lazy">
<img src="/img/buttons/misc/graphicdesign.gif" alt="graphic design is my passion"> <img src="/img/buttons/misc/graphicdesign.gif" alt="graphic design is my passion" loading="lazy">
<img src="/img/buttons/misc/gplv3.gif" alt="GPLv3 free software"> <img src="/img/buttons/misc/gplv3.gif" alt="GPLv3 free software" loading="lazy">
<img src="/img/buttons/misc/hl.gif" alt="half-life"> <img src="/img/buttons/misc/hl.gif" alt="half-life" loading="lazy">
<img src="/img/buttons/misc/h-free-anim.gif" alt="dis site is hentai FREE"> <img src="/img/buttons/misc/h-free-anim.gif" alt="dis site is hentai FREE" loading="lazy">
<img src="/img/buttons/misc/sprunk.gif" alt="sprunk"> <img src="/img/buttons/misc/sprunk.gif" alt="sprunk" loading="lazy">
<img src="/img/buttons/misc/tohell.gif" alt="go straight to hell"> <img src="/img/buttons/misc/tohell.gif" alt="go straight to hell" loading="lazy">
<img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')"> <img src="/img/buttons/misc/virusalert.gif" alt="virus alert! click here" onclick="alert('meow :3')" loading="lazy">
<img src="/img/buttons/misc/wii.gif" alt="wii"> <img src="/img/buttons/misc/wii.gif" alt="wii" loading="lazy">
<img src="/img/buttons/misc/www2.gif" alt="www"> <img src="/img/buttons/misc/www2.gif" alt="www" loading="lazy">
<img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer"> <img src="/img/buttons/misc/iemandatory.gif" alt="get mandatory internet explorer" loading="lazy">
<img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!"> <img src="/img/buttons/misc/learn_html.gif" alt="HTML - learn it today!" loading="lazy">
<a href="https://smokepowered.com" target="_blank"> <a href="https://smokepowered.com" target="_blank">
<img src="/img/buttons/misc/smokepowered.gif" alt="high on SMOKE"> <img src="/img/buttons/misc/smokepowered.gif" alt="high on SMOKE" loading="lazy">
</a> </a>
<a href="https://epicblazed.com" target="_blank"> <a href="https://epicblazed.com" target="_blank">
<img src="/img/buttons/misc/epicblazed.png" alt="epic blazed"> <img src="/img/buttons/misc/epicblazed.png" alt="epic blazed" loading="lazy">
</a> </a>
</div> </div>
</main> </main>

View file

@ -28,7 +28,7 @@
{{range $Album := .}} {{range $Album := .}}
<div class="music" id="{{$Album.Id}}" swap-url="/music/{{$Album.Id}}"> <div class="music" id="{{$Album.Id}}" swap-url="/music/{{$Album.Id}}">
<div class="music-artwork"> <div class="music-artwork">
<img src="{{$Album.ResolveArtwork}}" alt="{{$Album.Title}} artwork" width="128"> <img src="{{$Album.ResolveArtwork}}" alt="{{$Album.Title}} artwork" width="128" loading="lazy">
</div> </div>
<div class="music-details"> <div class="music-details">
<a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a> <a href="/music/{{$Album.Id}}"><h1 class="music-title">{{$Album.Title}}</h1></a>