100 lines
3.1 KiB
Go
100 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.loyso.art/frx/kurious/assets/kurious"
|
|
"git.loyso.art/frx/kurious/internal/common/config"
|
|
"git.loyso.art/frx/kurious/internal/common/generator"
|
|
"git.loyso.art/frx/kurious/internal/common/xcontext"
|
|
xhttp "git.loyso.art/frx/kurious/internal/kurious/ports/http"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
const (
|
|
pathParamLearningType = "learning_type"
|
|
pathParamThematicType = "thematic_type"
|
|
)
|
|
|
|
func makePathTemplate(params ...string) string {
|
|
var sb strings.Builder
|
|
for _, param := range params {
|
|
sb.WriteRune('/')
|
|
sb.WriteRune('{')
|
|
sb.WriteString(param)
|
|
sb.WriteRune('}')
|
|
}
|
|
|
|
return sb.String()
|
|
}
|
|
|
|
func setupHTTP(cfg config.HTTP, srv xhttp.Server, log *slog.Logger) *http.Server {
|
|
router := mux.NewRouter()
|
|
|
|
coursesAPI := srv.Courses()
|
|
|
|
router.Use(mux.CORSMethodMiddleware(router))
|
|
router.Use(middlewareLogger(log))
|
|
router.HandleFunc("/updatedesc", coursesAPI.UdpateDescription).Methods(http.MethodPost)
|
|
coursesRouter := router.PathPrefix("/courses").Subrouter()
|
|
coursesRouter.HandleFunc("/", coursesAPI.List).Methods(http.MethodGet)
|
|
coursesListLearningOnlyPath := makePathTemplate(pathParamLearningType)
|
|
coursesRouter.HandleFunc(coursesListLearningOnlyPath, coursesAPI.List).Methods(http.MethodGet)
|
|
coursesListFullPath := makePathTemplate(pathParamLearningType, pathParamThematicType)
|
|
coursesRouter.HandleFunc(coursesListFullPath, coursesAPI.List).Methods(http.MethodGet)
|
|
|
|
courseRouter := router.PathPrefix("/course").PathPrefix("/{course_id}").Subrouter()
|
|
courseRouter.HandleFunc("/", coursesAPI.Get).Methods(http.MethodGet)
|
|
courseRouter.HandleFunc("/short", coursesAPI.GetShort).Methods(http.MethodGet)
|
|
courseRouter.HandleFunc("/editdesc", coursesAPI.RenderEditDescription).Methods(http.MethodGet)
|
|
courseRouter.HandleFunc("/description", coursesAPI.UpdateCourseDescription).Methods(http.MethodPut)
|
|
|
|
if cfg.MountLive {
|
|
fs := http.FileServer(http.Dir("./assets/kurious/static/"))
|
|
router.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs)).Methods(http.MethodGet)
|
|
|
|
router.HandleFunc("/robots.txt", func(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, "./assets/kurious/robots.txt")
|
|
}).Methods(http.MethodGet)
|
|
} else {
|
|
fs := kurious.AsHTTPFileHandler()
|
|
router.PathPrefix("/").Handler(fs).Methods(http.MethodGet)
|
|
}
|
|
|
|
return &http.Server{
|
|
Addr: cfg.ListenAddr,
|
|
Handler: router,
|
|
}
|
|
}
|
|
|
|
func middlewareLogger(log *slog.Logger) mux.MiddlewareFunc {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
requestID := r.Header.Get("x-request-id")
|
|
if requestID == "" {
|
|
requestID = generator.RandomInt64ID()
|
|
}
|
|
ctx = xcontext.WithLogFields(ctx, slog.String("request_id", requestID))
|
|
|
|
xcontext.LogInfo(
|
|
ctx, log, "incoming request",
|
|
slog.String("method", r.Method),
|
|
slog.String("path", r.URL.Path),
|
|
)
|
|
|
|
start := time.Now()
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
elapsed := time.Since(start).Truncate(time.Millisecond)
|
|
|
|
xcontext.LogInfo(
|
|
ctx, log, "request processed",
|
|
slog.Duration("elapsed", elapsed),
|
|
)
|
|
})
|
|
}
|
|
}
|