package main import ( "log/slog" "net/http" "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" ) 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) courseRouter := coursesRouter.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), ) }) } }