impl server side
This commit is contained in:
118
src/server/server.go
Normal file
118
src/server/server.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"local/router"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
config Config
|
||||
gm *GameMaster
|
||||
*router.Router
|
||||
}
|
||||
|
||||
func NewServer(config Config, gm *GameMaster) *Server {
|
||||
return &Server{
|
||||
config: config,
|
||||
gm: gm,
|
||||
Router: router.New(),
|
||||
}
|
||||
}
|
||||
|
||||
func (server *Server) Routes() error {
|
||||
cases := map[string]map[string]http.HandlerFunc{
|
||||
fmt.Sprintf("%s/%s%s", server.config.Server.File.Prefix, router.Wildcard, router.Wildcard): map[string]http.HandlerFunc{
|
||||
http.MethodGet: server.File,
|
||||
},
|
||||
fmt.Sprintf("%s/games/%s", server.config.Server.API.Prefix, router.Wildcard): map[string]http.HandlerFunc{
|
||||
http.MethodGet: server.GameGet,
|
||||
http.MethodPost: server.GameInsert,
|
||||
},
|
||||
}
|
||||
|
||||
for path, spec := range cases {
|
||||
log.Println("listening for:", path)
|
||||
handler := server.ByMethod(spec)
|
||||
if err := server.Add(path, handler); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (server *Server) ByMethod(m map[string]http.HandlerFunc) http.HandlerFunc {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
foo, ok := m[r.Method]
|
||||
if ok {
|
||||
foo(w, r)
|
||||
} else {
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func (server *Server) File(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
s := http.FileServer(http.Dir(server.config.Server.File.Root))
|
||||
r.URL.Path = strings.TrimPrefix(r.URL.Path, server.config.Server.File.Prefix)
|
||||
s.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (server *Server) GameGet(w http.ResponseWriter, r *http.Request) {
|
||||
var gameID string
|
||||
err := router.Params(r, &gameID)
|
||||
if err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
resp, err := server.gm.GetGame(gameID)
|
||||
if err != nil {
|
||||
internalError(w, err.Error())
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (server *Server) GameInsert(w http.ResponseWriter, r *http.Request) {
|
||||
var gameID string
|
||||
err := router.Params(r, &gameID)
|
||||
if err != nil {
|
||||
badRequest(w, err.Error())
|
||||
return
|
||||
}
|
||||
err = server.gm.CreateGame(gameID)
|
||||
if err != nil {
|
||||
internalError(w, err.Error())
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(Game{})
|
||||
}
|
||||
|
||||
func notImpl(w http.ResponseWriter) {
|
||||
errHandler(w, http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
|
||||
}
|
||||
|
||||
func internalError(w http.ResponseWriter, message string) {
|
||||
errHandler(w, http.StatusInternalServerError, message)
|
||||
}
|
||||
|
||||
func badRequest(w http.ResponseWriter, message string) {
|
||||
errHandler(w, http.StatusBadRequest, message)
|
||||
}
|
||||
|
||||
func errHandler(w http.ResponseWriter, status int, message string) {
|
||||
w.WriteHeader(status)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"status": http.StatusText(status),
|
||||
"statusCode": status,
|
||||
"error": message,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user