Support plain HTTP mode for mc-proxy L7 deployment
Custom config package with optional TLS fields. When tls_cert/tls_key are empty, serves plain HTTP (behind mc-proxy which terminates TLS). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,28 +4,23 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
mcdslauth "git.wntrmute.dev/mc/mcdsl/auth"
|
||||
"git.wntrmute.dev/mc/mcdsl/config"
|
||||
"git.wntrmute.dev/mc/mcdsl/httpserver"
|
||||
|
||||
mcqconfig "git.wntrmute.dev/mc/mcq/internal/config"
|
||||
"git.wntrmute.dev/mc/mcq/internal/db"
|
||||
"git.wntrmute.dev/mc/mcq/internal/grpcserver"
|
||||
"git.wntrmute.dev/mc/mcq/internal/server"
|
||||
"git.wntrmute.dev/mc/mcq/internal/webserver"
|
||||
)
|
||||
|
||||
type mcqConfig struct {
|
||||
config.Base
|
||||
}
|
||||
|
||||
func serverCmd() *cobra.Command {
|
||||
var configPath string
|
||||
|
||||
@@ -42,7 +37,7 @@ func serverCmd() *cobra.Command {
|
||||
}
|
||||
|
||||
func runServer(configPath string) error {
|
||||
cfg, err := config.Load[mcqConfig](configPath, "MCQ")
|
||||
cfg, err := mcqconfig.Load(configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("load config: %w", err)
|
||||
}
|
||||
@@ -68,12 +63,11 @@ func runServer(configPath string) error {
|
||||
return fmt.Errorf("create auth client: %w", err)
|
||||
}
|
||||
|
||||
// HTTP server — all routes on one router.
|
||||
httpSrv := httpserver.New(cfg.Server, logger)
|
||||
httpSrv.Router.Use(httpSrv.LoggingMiddleware)
|
||||
// Build router with all routes.
|
||||
router := chi.NewRouter()
|
||||
|
||||
// Register REST API routes (/v1/*).
|
||||
server.RegisterRoutes(httpSrv.Router, server.Deps{
|
||||
server.RegisterRoutes(router, server.Deps{
|
||||
DB: database,
|
||||
Auth: authClient,
|
||||
Logger: logger,
|
||||
@@ -88,36 +82,22 @@ func runServer(configPath string) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("create web server: %w", err)
|
||||
}
|
||||
webSrv.RegisterRoutes(httpSrv.Router)
|
||||
webSrv.RegisterRoutes(router)
|
||||
|
||||
// Start gRPC server if configured.
|
||||
var grpcSrv *grpcserver.Server
|
||||
var grpcLis net.Listener
|
||||
if cfg.Server.GRPCAddr != "" {
|
||||
grpcSrv, err = grpcserver.New(cfg.Server.TLSCert, cfg.Server.TLSKey, grpcserver.Deps{
|
||||
DB: database,
|
||||
Authenticator: authClient,
|
||||
}, logger)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create gRPC server: %w", err)
|
||||
}
|
||||
grpcLis, err = net.Listen("tcp", cfg.Server.GRPCAddr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("listen gRPC on %s: %w", cfg.Server.GRPCAddr, err)
|
||||
}
|
||||
// Plain HTTP server (behind mc-proxy L7 which terminates TLS).
|
||||
httpSrv := &http.Server{
|
||||
Addr: cfg.Server.ListenAddr,
|
||||
Handler: router,
|
||||
ReadTimeout: cfg.Server.ReadTimeout.Duration,
|
||||
WriteTimeout: cfg.Server.WriteTimeout.Duration,
|
||||
IdleTimeout: cfg.Server.IdleTimeout.Duration,
|
||||
}
|
||||
|
||||
// Graceful shutdown.
|
||||
grpcServeStarted := false
|
||||
shutdownAll := func() {
|
||||
if grpcSrv != nil {
|
||||
grpcSrv.GracefulStop()
|
||||
} else if grpcLis != nil && !grpcServeStarted {
|
||||
_ = grpcLis.Close()
|
||||
}
|
||||
shutdownTimeout := 30 * time.Second
|
||||
if cfg.Server.ShutdownTimeout.Duration > 0 {
|
||||
shutdownTimeout = cfg.Server.ShutdownTimeout.Duration
|
||||
shutdownTimeout := cfg.Server.ShutdownTimeout.Duration
|
||||
if shutdownTimeout == 0 {
|
||||
shutdownTimeout = 30 * time.Second
|
||||
}
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
|
||||
defer cancel()
|
||||
@@ -127,19 +107,14 @@ func runServer(configPath string) error {
|
||||
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
|
||||
defer stop()
|
||||
|
||||
errCh := make(chan error, 2)
|
||||
|
||||
if grpcSrv != nil {
|
||||
grpcServeStarted = true
|
||||
go func() {
|
||||
logger.Info("gRPC server listening", "addr", grpcLis.Addr())
|
||||
errCh <- grpcSrv.Serve(grpcLis)
|
||||
}()
|
||||
}
|
||||
errCh := make(chan error, 1)
|
||||
|
||||
go func() {
|
||||
logger.Info("mcq starting", "version", version, "addr", cfg.Server.ListenAddr)
|
||||
errCh <- httpSrv.ListenAndServeTLS()
|
||||
err := httpSrv.ListenAndServe()
|
||||
if err != nil && err != http.ErrServerClosed {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
|
||||
select {
|
||||
|
||||
Reference in New Issue
Block a user