blob: a7f3e54a9920fbf23f23eb7cb14955d1c548bd56 [file] [log] [blame]
package main
import (
"flag"
"fmt"
"mime"
"net/http"
"regexp"
"strings"
"sync"
"code.hackerspace.pl/hscloud/go/mirko"
"github.com/golang/glog"
"code.hackerspace.pl/hscloud/hswaw/site/static"
)
var (
flagSitePublic string
)
type service struct {
// feeds is a map from atom feed name to atom feed. This is updated by a
// background worker.
feeds map[string]*atomFeed
// feedsMu locks the feeds field.
feedsMu sync.RWMutex
}
func main() {
flag.StringVar(&flagSitePublic, "site_public", "0.0.0.0:8080", "Address at which to serve public HTTP requests")
flag.Parse()
mi := mirko.New()
if err := mi.Listen(); err != nil {
glog.Exitf("Listen failed: %v", err)
}
s := &service{}
go s.feedWorker(mi.Context())
mux := http.NewServeMux()
s.registerHTTP(mux)
go func() {
glog.Infof("Listening for public HTTP at %v", flagSitePublic)
if err := http.ListenAndServe(flagSitePublic, mux); err != nil {
glog.Exit(err)
}
}()
if err := mi.Serve(); err != nil {
glog.Exitf("Serve failed: %v", err)
}
<-mi.Done()
}
var (
// staticRoutes define the resolution of static file paths into assets
// built into //hswaw/site/static, whose names correspond to their origin
// within the Bazel workspace.
// The regexp will be matched against the normalized within the URL. If it
// matches, its first group/submatch will be used to format the string
// corresponding to this regexp, and that string will be then used to
// retrieve a path embedded within //hswaw/site/static:static
// (go_embed_data).
//
// To see paths available within that go_embed_data, you can do:
// $ bazel build //hswaw/site/static:static
// $ grep -A100 'Data =' bazel-bin/hswaw/site/static/static.go
staticRoutes = map[*regexp.Regexp]string{
regexp.MustCompile(`^static/site/(.+)$`): "hswaw/site/static/%s",
regexp.MustCompile(`^static/leaflet/(.+)$`): "external/com_npmjs_leaflet/package/dist/%s",
}
)
// handleHTTPStatic uses staticRoutes to serve static files embedded within
// //hswaw/site/static.
func (s *service) handleHTTPStatic(w http.ResponseWriter, r *http.Request) {
path := strings.TrimPrefix(r.URL.Path, "/")
for from, to := range staticRoutes {
match := from.FindStringSubmatch(path)
if match == nil {
continue
}
to := fmt.Sprintf(to, match[1])
data, ok := static.Data[to]
if !ok {
continue
}
parts := strings.Split(path, ".")
ext := fmt.Sprintf(".%s", parts[len(parts)-1])
t := mime.TypeByExtension(ext)
w.Header().Set("Content-Type", t)
w.Write(data)
return
}
http.NotFound(w, r)
}
func (s *service) registerHTTP(mux *http.ServeMux) {
mux.HandleFunc("/static/", s.handleHTTPStatic)
mux.HandleFunc("/", s.handleIndex)
}