package main
import (
"compress/gzip"
"embed"
"fmt"
"log"
"net/http"
"os"
"regexp"
"strconv"
"strings"
)
const frontendPrefix = "client/build"
var hashRegex = regexp.MustCompile(`\.([0-9a-f]{8})\.`)
//go:embed client/build/static/js/*.js
//go:embed client/build/static/js/*LICENSE*
//go:embed client/build/static/css/*.css
//go:embed client/build/index.html
var content embed.FS
func writeErr(w http.ResponseWriter, err error) bool {
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Println(err)
return true
}
return false
}
func handler(w http.ResponseWriter, r *http.Request) {
requestPath := r.URL.Path
fmt.Println(requestPath)
optionalSlash := ""
if !strings.HasPrefix(requestPath, "/") {
optionalSlash = "/"
}
if requestPath == "" || requestPath == "/" {
index, err := content.ReadFile(frontendPrefix + "/index.html")
if writeErr(w, err) {
return
}
w.Write(index)
return
}
file, err := content.ReadFile(frontendPrefix + optionalSlash + requestPath)
if writeErr(w, err) {
return
}
hash := hashRegex.FindStringSubmatch(requestPath)
if hash != nil && len(hash) >= 2 {
if r.Header.Get("If-None-Match") == hash[1] {
w.WriteHeader(http.StatusNotModified)
return
}
w.Header().Add("ETag", hash[1])
}
desiredEncodings := r.Header.Get("Accept-Encoding")
if w.Header().Get("Content-Type") == "" {
w.Header().Set("Content-Type", http.DetectContentType(file))
}
if strings.Contains(desiredEncodings, "gzip") {
w.Header().Add("Content-Encoding", "gzip")
gz := gzip.NewWriter(w)
defer gz.Close()
gz.Write(file)
return
}
w.Write(file)
}
func main() {
http.HandleFunc("/", handler)
numArgs := len(os.Args)
port := "8080"
if numArgs > 1 {
portNumber, err := strconv.Atoi(os.Args[1])
if err == nil && portNumber >= 1 && portNumber <= 65535 {
port = os.Args[1]
}
}
log.Fatal(http.ListenAndServe(":"+port, nil))
}