first version

This commit is contained in:
Aurélie Delhaie
2023-05-07 22:34:30 +02:00
commit 784679592d
13 changed files with 394 additions and 0 deletions

148
server/server.go Normal file
View File

@@ -0,0 +1,148 @@
package server
import (
"embed"
_ "embed"
"errors"
"fmt"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/mileusna/useragent"
"html/template"
"log"
"net/http"
"os"
"retroHub/data"
"strings"
)
type injector struct {
Version string
}
type userAgentInjector struct {
injector
UserAgent useragent.UserAgent
}
type providerInjector struct {
injector
Provider data.Provider
}
type errorInjector struct {
injector
StatusCode int
StatusText string
}
const version string = "0.1"
//go:embed templates
var templates embed.FS
var (
provider data.Provider
indexTemplate *template.Template
uaTemplate *template.Template
errTemplate *template.Template
errLog *log.Logger
)
func init() {
indexTemplate = template.Must(template.ParseFS(templates, "templates/base.html", "templates/index.html"))
uaTemplate = template.Must(template.ParseFS(templates, "templates/base.html", "templates/ua.html"))
errTemplate = template.Must(template.ParseFS(templates, "templates/base.html", "templates/error.html"))
errLog = log.New(os.Stderr, "", log.LstdFlags)
}
func Serve(contentProvider data.Provider, port uint) error {
if contentProvider == nil {
return errors.New("content provider cannot be nil")
}
provider = contentProvider
r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(panicHandler)
r.NotFound(notFoundHandler)
r.Get("/", indexHandler)
r.Get("/ua", userAgentHandler)
log.Printf("the server is up and running on %d", port)
err := http.ListenAndServe(fmt.Sprintf(":%d", port), r)
if err != nil {
return err
}
return nil
}
func panicHandler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if r := recover(); r != nil {
errLog.Println("ERROR", r)
injectedData := errorInjector{
injector: injector{
Version: version,
},
StatusCode: http.StatusInternalServerError,
StatusText: "Internal Server Error",
}
w.WriteHeader(http.StatusInternalServerError)
err := errTemplate.ExecuteTemplate(w, "base", injectedData)
if err != nil {
errLog.Println("ERROR", err)
}
}
}()
next.ServeHTTP(w, r)
})
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
injectedData := providerInjector{
injector: injector{
Version: version,
},
Provider: provider,
}
err := indexTemplate.ExecuteTemplate(w, "base", injectedData)
if err != nil {
errLog.Println("ERROR", err)
}
}
func userAgentHandler(w http.ResponseWriter, r *http.Request) {
injectedData := userAgentInjector{
injector: injector{
Version: version,
},
}
userAgent := strings.TrimSpace(r.UserAgent())
if len(userAgent) > 0 {
injectedData.UserAgent = useragent.Parse(userAgent)
}
err := uaTemplate.ExecuteTemplate(w, "base", injectedData)
if err != nil {
errLog.Println("ERROR", err)
}
}
func notFoundHandler(w http.ResponseWriter, _ *http.Request) {
injectedData := errorInjector{
injector: injector{
Version: version,
},
StatusCode: http.StatusNotFound,
StatusText: "Not Found",
}
w.WriteHeader(http.StatusNotFound)
err := errTemplate.ExecuteTemplate(w, "base", injectedData)
if err != nil {
errLog.Println("ERROR", err)
}
}