blob: 163d8a04825457e187989768f5cb4d8569961621 [file] [log] [blame]
// Copyright 2021 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"context"
"flag"
"fmt"
"log"
"net/http"
"os"
"os/signal"
"path/filepath"
"runtime"
"text/template"
"time"
)
var (
host string
port int
procs int
assetsRoot string
)
func init() {
flag.StringVar(&host, "host", "localhost", "host to serve on")
flag.IntVar(&port, "port", 8081, "port to serve on")
flag.IntVar(&procs, "procs", runtime.GOMAXPROCS(-1), "how many processors to use")
flag.StringVar(&assetsRoot, "assets", "./assets", "directory to serve assets from")
}
var frontPage = template.Must(template.New("front").Parse(`
{{- range . -}}
{{.}}
{{end -}}
`))
func main() {
flag.Parse()
runtime.GOMAXPROCS(procs)
var images []string
filepath.Walk(assetsRoot, func(path string, info os.FileInfo, err error) error {
if err != nil {
log.Printf("warning: failed to walk %s: %v", path, err)
return nil
}
if info.IsDir() {
// Ignore directories.
return nil
}
relPath, _ := filepath.Rel(assetsRoot, path)
switch filepath.Ext(path) {
case ".jpg", ".png", ".gif":
images = append(images, relPath)
default:
}
return nil
})
for i, img := range images {
images[i] = filepath.Join("/static", img)
log.Printf("Image: %s", images[i])
}
ctx := context.Background()
ctx, cancel := signal.NotifyContext(ctx, os.Interrupt)
defer cancel()
// Set up a done channel.
http.Handle("/static/", http.FileServer(http.Dir(assetsRoot)))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
if err := frontPage.Execute(w, images); err != nil {
http.Error(w, fmt.Sprintf("Internal server error: %s", err.Error()), 500)
return
}
})
server := &http.Server{Addr: fmt.Sprintf("%s:%d", host, port), Handler: http.DefaultServeMux}
go func() {
err := server.ListenAndServe()
if err != nil && err != http.ErrServerClosed {
log.Fatalf("Server error listening/serving: %s", err)
}
}()
// Wait for a signal to stop.
<-ctx.Done()
// Shut down the server cleanly.
exitCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := server.Shutdown(exitCtx); err != nil {
log.Printf("Clean shutdown failed: %v", err)
return
}
log.Print("Shut down successfully. Goodbye!")
}