Skip to content

Instantly share code, notes, and snippets.

@caulagi
Created April 9, 2016 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save caulagi/81decc6abc55c48ad1f8cd6c6026d430 to your computer and use it in GitHub Desktop.
Save caulagi/81decc6abc55c48ad1f8cd6c6026d430 to your computer and use it in GitHub Desktop.
A static file server in Go
// A simple HTTP static file server.
//
// Usage:
// go run --root ~/Pictures --port 8001
//
package main
import (
"errors"
"flag"
"fmt"
"log"
"net/http"
"os"
"regexp"
)
// Router is a http.Handler that dispatches requests to different
// handler functions.
type Router struct {
// Root directory for serving files
root string
}
// Override the main http method to only serve files
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if !isValidPath(req.URL.Path) {
http.NotFound(w, req)
return
}
fs := http.FileServer(http.Dir(r.root))
fs.ServeHTTP(w, req)
}
// Check if the path is something we want to serve
func isValidPath(path string) bool {
isValid, err := regexp.Compile(`^([[:alnum:]/]+)(.png|.jpg)$`)
if err != nil {
log.Fatal(err)
return false
}
return isValid.MatchString(path)
}
// Check if the root path specified for the server is valid
func checkRoot(root string) error {
_, err := os.Stat(root)
if err != nil {
return errors.New(fmt.Sprintf("No such directory: %s", root))
}
return nil
}
var port = flag.String("port", ":8001", "Port on which the server will listen")
var root = flag.String("root", "/var/www/example.com/static", "Root directory from where the files will be served")
func init() {
flag.Parse()
log.Println("Serving from", *root, "on port", *port)
err := checkRoot(*root)
if err != nil {
log.Fatal(err)
}
}
func main() {
err := http.ListenAndServe(*port, &Router{root: *root})
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment