So I am new to Go and trying it out to build a simple web server. One part I am having trouble with is that I want to serve static files with dynamic static urls (to enable long caching by the browser). For example, I might have this url:
/static/876dsf5g87s6df5gs876df5g/application.js
But I want to serve the file located at:
/build/application.js
How would I go about this with Go / Negroni / Gorilla Mux?
Have you already decided on how to record/persist the "random" part of the URL? DB? In memory (i.e. not across restarts)? If not, crypto/sha1
the file(s) on start-up, and store the resultant SHA-1 hash in a map/slice.
Otherwise, a route like (assuming Gorilla) r.Handle("/static/{cache_id}/{filename}", YourFileHandler)
would work.
package main
import (
"log"
"mime"
"net/http"
"path/filepath"
"github.com/gorilla/mux"
)
func FileServer(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["cache_id"]
// Logging for the example
log.Println(id)
// Check if the id is valid, else 404, 301 to the new URL, etc - goes here!
// (this is where you'd look up the SHA-1 hash)
// Assuming it's valid
file := vars["filename"]
// Logging for the example
log.Println(file)
// Super simple. Doesn't set any cache headers, check existence, avoid race conditions, etc.
w.Header().Set("Content-Type", mime.TypeByExtension(filepath.Ext(file)))
http.ServeFile(w, r, "/Users/matt/Desktop/"+file)
}
func IndexHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello!\n"))
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", IndexHandler)
r.HandleFunc("/static/{cache_id}/{filename}", FileServer)
log.Fatal(http.ListenAndServe(":4000", r))
}
That should work out of the box, but I can't promise it's production ready. Personally, I just use nginx to serve my static files and benefit from it's file handler cache, solid gzip implementation, etc, etc.