moth/cmd/mothd/httpd.go

146 lines
3.4 KiB
Go
Raw Normal View History

2020-02-29 16:53:08 -07:00
package main
import (
"log"
2020-02-29 22:37:22 -07:00
"net/http"
2020-02-29 16:53:08 -07:00
"strings"
)
type HTTPServer struct {
*http.ServeMux
2020-02-29 22:37:22 -07:00
Puzzles PuzzleProvider
Theme ThemeProvider
State StateProvider
2020-02-29 16:53:08 -07:00
}
2020-02-29 22:37:22 -07:00
func NewHTTPServer(base string, theme ThemeProvider, state StateProvider, puzzles PuzzleProvider) *HTTPServer {
2020-02-29 16:53:08 -07:00
h := &HTTPServer{
ServeMux: http.NewServeMux(),
2020-02-29 22:37:22 -07:00
Puzzles: puzzles,
Theme: theme,
State: state,
2020-02-29 16:53:08 -07:00
}
2020-02-29 17:12:19 -07:00
base = strings.TrimRight(base, "/")
2020-02-29 16:53:08 -07:00
h.HandleFunc(base+"/", h.ThemeHandler)
h.HandleFunc(base+"/state", h.StateHandler)
h.HandleFunc(base+"/register", h.RegisterHandler)
h.HandleFunc(base+"/answer", h.AnswerHandler)
h.HandleFunc(base+"/content/", h.ContentHandler)
return h
}
func (h *HTTPServer) Run(bindStr string) {
log.Printf("Listening on %s", bindStr)
log.Fatal(http.ListenAndServe(bindStr, h))
}
type MothResponseWriter struct {
statusCode *int
http.ResponseWriter
}
func (w MothResponseWriter) WriteHeader(statusCode int) {
*w.statusCode = statusCode
w.ResponseWriter.WriteHeader(statusCode)
}
// This gives Instances the signature of http.Handler
func (h *HTTPServer) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
w := MothResponseWriter{
2020-02-29 22:37:22 -07:00
statusCode: new(int),
2020-02-29 16:53:08 -07:00
ResponseWriter: wOrig,
}
h.ServeMux.ServeHTTP(w, r)
log.Printf(
"%s %s %s %d\n",
r.RemoteAddr,
r.Method,
r.URL,
*w.statusCode,
)
}
func (h *HTTPServer) ThemeHandler(w http.ResponseWriter, req *http.Request) {
path := req.URL.Path
if path == "/" {
path = "/index.html"
}
2020-02-29 22:37:22 -07:00
f, err := h.Theme.Open(path)
2020-02-29 16:53:08 -07:00
if err != nil {
http.NotFound(w, req)
return
}
defer f.Close()
2020-02-29 22:37:22 -07:00
mtime, _ := h.Theme.ModTime(path)
2020-02-29 16:53:08 -07:00
http.ServeContent(w, req, path, mtime, f)
}
func (h *HTTPServer) StateHandler(w http.ResponseWriter, req *http.Request) {
2020-02-29 18:36:59 -07:00
var state struct {
Config struct {
2020-02-29 22:37:22 -07:00
Devel bool
}
Messages string
TeamNames map[string]string
PointsLog []Award
Puzzles map[string][]int
2020-02-29 18:36:59 -07:00
}
2020-02-29 22:37:22 -07:00
teamId := req.FormValue("id")
export := h.State.Export(teamId)
state.Messages = export.Messages
state.TeamNames = export.TeamNames
state.PointsLog = export.PointsLog
state.Puzzles = make(map[string][]int)
2020-03-01 13:27:49 -07:00
//XXX: move to brains.go
for _, category := range h.Puzzles.Inventory() {
maxSolved := 0
// XXX: We don't have to iterate the log for every category
for _, a := range export.PointsLog {
if (a.Category == category.Name) && (a.Points > maxSolved) {
maxSolved = a.Points
}
}
// Append sentry (end of puzzles)
allPuzzles := append(category.Puzzles, 0)
puzzles := make([]int, 0, len(allPuzzles))
for i, val := range allPuzzles {
puzzles = allPuzzles[:i+1]
if val > maxSolved {
break
}
}
state.Puzzles[category.Name] = puzzles
}
2020-02-29 18:36:59 -07:00
JSONWrite(w, state)
2020-02-29 16:53:08 -07:00
}
func (h *HTTPServer) RegisterHandler(w http.ResponseWriter, req *http.Request) {
2020-02-29 22:37:22 -07:00
teamId := req.FormValue("id")
teamName := req.FormValue("name")
if err := h.State.SetTeamName(teamId, teamName); err != nil {
JSendf(w, JSendFail, "not registered", err.Error())
} else {
JSendf(w, JSendSuccess, "registered", "Team ID registered")
}
2020-02-29 16:53:08 -07:00
}
func (h *HTTPServer) AnswerHandler(w http.ResponseWriter, req *http.Request) {
2020-02-29 18:36:59 -07:00
JSendf(w, JSendFail, "unimplemented", "I haven't written this yet")
2020-02-29 16:53:08 -07:00
}
func (h *HTTPServer) ContentHandler(w http.ResponseWriter, req *http.Request) {
2020-02-29 18:36:59 -07:00
path := req.URL.Path
if path == "/" {
path = "/puzzle.json"
}
JSendf(w, JSendFail, "unimplemented", "I haven't written this yet")
2020-02-29 16:53:08 -07:00
}