package main
import (
"time""github.com/SaulDoesCode/echo-memfile""github.com/labstack/echo"
)
funcmain() {
server:=echo.New() // your echo instanceassetsDir:="./assets"// directory containing your static assetsdevmode:=true// devmode will mostly log what's happening// MemFileInstance: read files and apply the middlewaremfi:=memfile.New(server, assetsDir, devmode)
// Keep your files updated when you're developingifdevmode {
mfi.UpdateOnInterval(time.Second*1)
}
server.Start(":1323")
}http://localhost:1323/ -> ./assets/index.html
http://localhost:1323/blog -> ./assets/blog/index.html
mfi = MemFileInstance
frommfi := memfile.New(server *echo.Echo, assetsDir string, devmode bool)
// if you want to keep your files updated you can// 1 - Update them manually as needed// this reads the directory and updates files and etags as neededmfi.Update()
// 2 - Update them regularly on an interval// this runs memfile.Update every 5 secondsmfi.UpdateOnInterval(time.Second*5)
// to stop the interval updaterticker:=mfi.UpdateOnInterval(time.Second*5)
ifNeedsToStop {
ticker.Stop()
}location:="../secret_files/pwd.txt"route:="/secrets/pwd"err:=mfi.CacheFile(location, route)
iferr!=nil {
// ...
}
// GET http://localhost:1323/secrets/pwd -> pwd.txtserver.GET("/resource/", func(c echo.Context) error {
ifresult, ok:=mfi.Cached.Load("/resource.json"); ok {
returnmfi.ServeMF(c, result.(*memfile.MemFile))
}
returnc.JSON(404, map[string]string{
"err": "out of luck no resource here",
})
})
// orserver.GET("/resource/", func(c echo.Context) error {
returnmfi.ServeFile(c, "/resource.json")
})
// or shorthandmfi.ServeMemFile("/resource", "/resource.json")
// NOTE: the resource's string corresponds to files under the assets dir// "./assets/resource.json" -> "/resource.json" ./assets
> index.html
> styles.css
> picture.jpg
> index.html.push
index.html.push is essentially just a json array containing serve routes to push with your html file
["/styles.css", "/picture.jpg"]Use this method for best results because manually modifying MemFiles can lead to corruption (in memory, your files are safe) SetPushAssets uses a mutex lock and unlock internally to avoid concurrent read-write related issues.
mfi.SetPushAssets("/route.html", []string{"/route.css", "/route.js"})result, exists:=mfi.Cached.Load("/subdir/index.html")
ifexists {
result.(*memfile.MemFile).PushAssets= []string{"/js/rilti.min.js", "/css/bulma.min.css"}
}
// note if you're doing it this way do it before the server starts// because of potential MemFile corruption from concurrent read-write issues// MFI.SetPushAssets uses mutex locks internally to avoid this.New(server *echo.Echo, dir string, devmode bool) MemFileInstance.CompressBytes(data []byte) ([]byte, error)gzip a byte slice.ServeMemFile(res http.ResponseWriter, req *http.Request, memFile MemFile, CacheControl string) error.ServablePath(dir string, loc string) stringcleans a filepath (under dir) for use as a url.RandBytes(size int) []byte.RandStr(size int) string.MemFileInstance{}.MemFile{}
.CacheFile(location string, servePath string) errorread a file and serve it at a particular route.Update()check files for changes and update accordingly.UpdateOnInterval(interval time.Duration) *time.TickerKeep updating regularly on a duration.ServeFile(c echo.Context, filename string) error.ServeMF(c echo.Context, memFile *MemFile) error.ServeMemFile(route string, filename string)shorthand handler.Serve(res http.ResponseWriter, req *http.Request, filename string) errorfor other middleware etc..CacheControlthe Cache-Control header is"private, must-revalidate"by default, but you can change it.DevMode.Cached:*sync.Map, this contains all the MemFile's in an Instance [assumed types (key string, value MemFile)]