This repository has been archived on 2023-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
openskins/runtime/webserver.go

228 lines
4.8 KiB
Go

package runtime
import (
"bytes"
"encoding/json"
"fmt"
"github.com/gorilla/mux"
"github.com/josephbmanley/OpenSkins-Common/datastore"
"github.com/josephbmanley/OpenSkins-Common/datatypes"
"github.com/josephbmanley/OpenSkins/pluginmanager"
"io"
"log"
"net/http"
)
var activeSkinstore datastore.Skinstore
var activeUserstore datastore.Userstore
func healthCheck(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Service is healthy!")
}
func getCharacter(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(501)
return
vars := mux.Vars(r)
userID := vars["user"]
charID := vars["char"]
user, err := activeUserstore.GetUser(userID)
// Check if there was an error getting the user
if err != nil {
log.Printf("An error occured when getting a character: %v", err.Error())
w.WriteHeader(500)
return
}
// Check if user exists
if user == nil {
w.WriteHeader(404)
return
}
// Find character
for _, character := range user.Characters {
if character.UID == charID {
json.NewEncoder(w).Encode(character) // Return character Json
return // Return 200
}
}
// Return 404
w.WriteHeader(404)
return
}
func createCharacter(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(501)
return
vars := mux.Vars(r)
userID := vars["user"]
charID := vars["char"]
user, err := activeUserstore.GetUser(userID)
// Check if there was an error getting the user
if err != nil {
log.Printf("CREATE CHARACTER - Failed to get user: %v", err.Error())
w.WriteHeader(500)
return
}
// Check if user exists
if user == nil {
w.WriteHeader(400)
w.Write([]byte("User does not exist!"))
return
}
// Check if character already exists
for _, character := range user.Characters {
if character.UID == charID {
w.WriteHeader(400)
w.Write([]byte("Character already exists!"))
return
}
}
newCharacter := datatypes.Character{
UID: charID,
Skin: datatypes.Skin{
UID: "none",
},
}
// Add character to user object
user.Characters = append(user.Characters, newCharacter)
err = activeUserstore.SetUser(user)
if err != nil {
log.Printf("CREATE CHARACTER - Failed to set user %v", err.Error())
w.WriteHeader(500)
}
return
}
func getSkin(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
skinID := vars["skin"]
// Get skin
skin, err := activeSkinstore.GetSkin(skinID)
if err != nil {
log.Printf("GET SKIN - Failed to get skin %v", err.Error())
w.WriteHeader(500)
}
// Check if skin exists
if skin == nil {
w.WriteHeader(404)
return
}
json.NewEncoder(w).Encode(skin) // Return skin Json
return // Return 200
}
func createSkin(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
skinID := vars["skin"]
// Lookup skin object
skin, err := activeSkinstore.GetSkin(skinID)
if err != nil {
log.Printf("CREATE SKIN - Failed to get skin: %v", err.Error())
w.WriteHeader(500)
return
}
// Check if skin exists
if skin != nil {
w.WriteHeader(400)
w.Write([]byte("Skin already exists!"))
return
}
// Load skin data from request
skinBytes, err := readfile(r, "skin")
if err != nil {
log.Printf("CREATE SKIN - Failed to read upload: %v", err.Error())
}
// Verify data exists
if skinBytes == nil {
w.WriteHeader(400)
w.Write([]byte("Missing skin data!"))
return
}
// Create new skin object
err = activeSkinstore.AddSkin(skinID, skinBytes)
// Validate skin creation
if err != nil {
log.Printf("CREATE SKIN - Failed to add skin: %v", err.Error())
w.WriteHeader(500)
return
}
return // Return 200
}
// Helper function to read a file from a request form
func readfile(r *http.Request, fileName string) ([]byte, error) {
err := r.ParseMultipartForm(32 << 20) // Limit upload size
if err != nil {
return nil, err
}
var buf bytes.Buffer
file, _, err := r.FormFile(fileName)
if err != nil {
return nil, err
}
defer file.Close()
// Copy the file data to my buffer
_, err = io.Copy(&buf, file)
if err != nil {
return nil, err
}
contents := buf.Bytes() // Get data
buf.Reset() // Clear buffer
return contents, nil
}
// StartWebserver starts the webserver
func StartWebserver(port int) {
activeSkinstore = pluginmanager.LoadedSkinstores[0] // Load first skinstore
// Intialize router
myRouter := mux.NewRouter().StrictSlash(true)
// Health check path
myRouter.HandleFunc("/health", healthCheck).Methods("GET")
// Character routes
myRouter.HandleFunc("/get/character/{user}/{char}", getCharacter).Methods("GET")
myRouter.HandleFunc("/create/character/{user}/{char}", createCharacter).Methods("POST")
// Skin routes
myRouter.HandleFunc("/get/skin/{skin}", getSkin).Methods("GET")
myRouter.HandleFunc("/create/skin/{skin}", createSkin).Methods("POST")
// Run webserver
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), myRouter))
}