62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
|
|
package server
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"errors"
|
||
|
|
"log/slog"
|
||
|
|
"net/http"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"github.com/go-chi/chi/v5"
|
||
|
|
|
||
|
|
"github.com/VictorVargas/rony-chat-bot/internal/config"
|
||
|
|
)
|
||
|
|
|
||
|
|
type Server struct {
|
||
|
|
httpSrv *http.Server
|
||
|
|
}
|
||
|
|
|
||
|
|
func New(cfg *config.Config, h *Handlers) *Server {
|
||
|
|
r := chi.NewRouter()
|
||
|
|
|
||
|
|
r.Use(RequestID)
|
||
|
|
r.Use(Logging)
|
||
|
|
r.Use(CORS(cfg.Server.CORSOrigins))
|
||
|
|
|
||
|
|
if cfg.Server.RateLimit.RequestsPerMinute > 0 {
|
||
|
|
r.Use(RateLimit(cfg.Server.RateLimit))
|
||
|
|
}
|
||
|
|
|
||
|
|
r.Get("/", func(w http.ResponseWriter, _ *http.Request) {
|
||
|
|
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
|
||
|
|
_, _ = w.Write([]byte("Rony Chat Bot — see /api/health, /api/info, POST /api/chat\n"))
|
||
|
|
})
|
||
|
|
|
||
|
|
r.Route("/api", func(r chi.Router) {
|
||
|
|
r.Post("/chat", h.Chat)
|
||
|
|
r.Post("/reindex", h.Reindex)
|
||
|
|
r.Get("/health", h.Health)
|
||
|
|
r.Get("/info", h.Info)
|
||
|
|
})
|
||
|
|
|
||
|
|
srv := &http.Server{
|
||
|
|
Addr: cfg.Addr(),
|
||
|
|
Handler: r,
|
||
|
|
ReadTimeout: time.Duration(cfg.Server.ReadTimeoutMS) * time.Millisecond,
|
||
|
|
WriteTimeout: 0, // SSE streams must not be cut off by WriteTimeout
|
||
|
|
IdleTimeout: 120 * time.Second,
|
||
|
|
}
|
||
|
|
return &Server{httpSrv: srv}
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *Server) Start() error {
|
||
|
|
slog.Info("http server starting", "addr", s.httpSrv.Addr)
|
||
|
|
if err := s.httpSrv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (s *Server) Shutdown(ctx context.Context) error {
|
||
|
|
return s.httpSrv.Shutdown(ctx)
|
||
|
|
}
|