package simpleserver import ( "fmt" "io/ioutil" "net/http" "os" "os/signal" "path/filepath" ) func setContentType(w http.ResponseWriter, ext string) { var t string switch ext { case ".html": t = "text/html" case ".js": t = "text/javascript" default: t = "" } if t != "" { w.Header().Add("Content-Type", t) } } func viewHandler(root string, w http.ResponseWriter, r *http.Request) { relativePath := filepath.FromSlash(r.URL.Path[1:]) file := filepath.Join(root, relativePath) setContentType(w, filepath.Ext(relativePath)) info, err := os.Stat(file) if err != nil { fmt.Fprint(w, err) return } if info.IsDir() { file = filepath.Join(file, "index.html") } fmt.Println("GET " + file) content, _ := ioutil.ReadFile(file) fmt.Fprint(w, string(content)) } func Serve(root string) { address := "127.0.0.1:8000" fmt.Println("Serving " + root + " at http://" + address + " ...") fmt.Println("Use Ctrl+C to exit") fmt.Println("(This is not a production web server, don't get any funny ideas)") http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { viewHandler(root, w, r) }) srv := &http.Server{Addr: address} c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) go func() { <-c fmt.Println("Received interrupt, closing...") srv.Close() }() err := srv.ListenAndServe() if err != nil && err != http.ErrServerClosed { fmt.Fprintln(os.Stderr, err) } }