mirror of https://github.com/dirtbags/moth.git
check in other important files
This commit is contained in:
parent
0bc8faa5ec
commit
ffc705ec8b
|
@ -0,0 +1,99 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"log"
|
||||
"strings"
|
||||
"github.com/dirtbags/moth/jsend"
|
||||
)
|
||||
|
||||
type HTTPServer struct {
|
||||
PuzzleProvider
|
||||
ThemeProvider
|
||||
StateProvider
|
||||
*http.ServeMux
|
||||
}
|
||||
|
||||
func NewHTTPServer(base string, theme ThemeProvider, state StateProvider, puzzles PuzzleProvider) (*HTTPServer) {
|
||||
h := &HTTPServer{
|
||||
ThemeProvider: theme,
|
||||
StateProvider: state,
|
||||
PuzzleProvider: puzzles,
|
||||
ServeMux: http.NewServeMux(),
|
||||
}
|
||||
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{
|
||||
statusCode: new(int),
|
||||
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 strings.Contains(path, "..") {
|
||||
http.Error(w, "Invalid URL path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if path == "/" {
|
||||
path = "/index.html"
|
||||
}
|
||||
|
||||
f, err := h.ThemeProvider.Open(path)
|
||||
if err != nil {
|
||||
http.NotFound(w, req)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
mtime, _ := h.ThemeProvider.ModTime(path)
|
||||
http.ServeContent(w, req, path, mtime, f)
|
||||
}
|
||||
|
||||
|
||||
func (h *HTTPServer) StateHandler(w http.ResponseWriter, req *http.Request) {
|
||||
jsend.Write(w, jsend.Fail, "unimplemented", "I haven't written this yet")
|
||||
}
|
||||
|
||||
func (h *HTTPServer) RegisterHandler(w http.ResponseWriter, req *http.Request) {
|
||||
jsend.Write(w, jsend.Fail, "unimplemented", "I haven't written this yet")
|
||||
}
|
||||
|
||||
func (h *HTTPServer) AnswerHandler(w http.ResponseWriter, req *http.Request) {
|
||||
jsend.Write(w, jsend.Fail, "unimplemented", "I haven't written this yet")
|
||||
}
|
||||
|
||||
func (h *HTTPServer) ContentHandler(w http.ResponseWriter, req *http.Request) {
|
||||
jsend.Write(w, jsend.Fail, "unimplemented", "I haven't written this yet")
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
module github.com/dirtbags/moth
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/namsral/flag v1.7.4-pre
|
||||
github.com/spf13/afero v1.2.2
|
||||
)
|
|
@ -0,0 +1,6 @@
|
|||
github.com/namsral/flag v1.7.4-pre h1:b2ScHhoCUkbsq0d2C15Mv+VU8bl8hAXV8arnWiOHNZs=
|
||||
github.com/namsral/flag v1.7.4-pre/go.mod h1:OXldTctbM6SWH1K899kPZcf65KxJiD7MsceFUpB5yDo=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
@ -0,0 +1,39 @@
|
|||
package jsend
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// This provides a JSend function for MOTH
|
||||
// https://github.com/omniti-labs/jsend
|
||||
|
||||
const (
|
||||
Success = "success"
|
||||
Fail = "fail"
|
||||
Error = "error"
|
||||
)
|
||||
|
||||
func Write(w http.ResponseWriter, status, short string, format string, a ...interface{}) {
|
||||
resp := struct{
|
||||
Status string `json:"status"`
|
||||
Data struct {
|
||||
Short string `json:"short"`
|
||||
Description string `json:"description"`
|
||||
} `json:"data"`
|
||||
}{}
|
||||
resp.Status = status
|
||||
resp.Data.Short = short
|
||||
resp.Data.Description = fmt.Sprintf(format, a...)
|
||||
|
||||
respBytes, err := json.Marshal(resp)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK) // RFC2616 makes it pretty clear that 4xx codes are for the user-agent
|
||||
w.Write(respBytes)
|
||||
}
|
Loading…
Reference in New Issue