Skip to content

Instantly share code, notes, and snippets.

@ericjster
Last active February 10, 2021 00:13
Show Gist options
  • Save ericjster/8186e6d3f5a12cc6e4e895e4ab237027 to your computer and use it in GitHub Desktop.
Save ericjster/8186e6d3f5a12cc6e4e895e4ab237027 to your computer and use it in GitHub Desktop.
go simpleserver

Simple Server

This is a small golang program to serve files via http. The files are restricted to the base directory and its children, or a specified directory. You will see a nice directory listing in the browser. It is meant to be used with *.html, *.png, and other files.

To use it: go build && ./simpleserver ..

Then in your browser, navigate to: http://localhost:8000/

. (dummy file to change name of gist)
package main
// Serve a web page for files.
//
// To see cache behavior: curl -I localhost:8000/foo
// See also: http FileServer example (DotFileHiding, StripPrefix), and Dir().
import (
"log"
"net/http"
"os"
"path/filepath"
"strings"
)
const port = ":8001"
var baseDir = "."
// Serve a file
func handleServeFile(w http.ResponseWriter, r *http.Request) {
// log.Printf("Got a request for serve file:%s\n", r.URL.Path)
// log.Printf(" Method:%s\n", r.Method)
// log.Printf(" Path:%s\n", r.URL.Path)
// log.Printf(" Query:%v\n", r.URL.Query())
file := r.URL.Path
// We guard against "..", which also disallows filename having two dots.
// This is actually unnecessary since http.ServerFile also does a check, and
// their check is smarter.
if strings.Contains(file, "..") {
log.Println("Disallowed:" + file)
w.WriteHeader(http.StatusNotFound)
return
}
path := filepath.Join(baseDir, file)
log.Println(path)
http.ServeFile(w, r, path)
}
func main() {
log.SetFlags(log.Flags() | log.Lmicroseconds)
if len(os.Args) == 2 {
baseDir = os.Args[1]
} else if len(os.Args) != 1 {
log.Fatalf("Expecting either no arguments or the base directory")
}
// We must specify the baseDir as absolute, because ServeFile will reject
// requests where r.URL.Path contains a ".." path element.
log.Printf("Using as base directory::%s\n", baseDir)
var err error
baseDir, err = filepath.Abs(baseDir)
if err != nil {
log.Fatal("Cannot get absolute directory for the base directory:", baseDir)
}
log.Printf("Using as base directory::%s\n", baseDir)
log.Printf("About to serve on port:%s\n", port)
http.HandleFunc("/", handleServeFile)
if err := http.ListenAndServe(port, nil); err != nil {
panic(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment