Files
2026-07-15 22:42:31 +08:00

92 lines
2.7 KiB
Go

package connectserver
import (
"errors"
"fmt"
"net/http"
"sync/atomic"
"connectrpc.com/connect"
"github.com/XingfenD/yoresee_doc/internal/repository"
"github.com/redis/go-redis/v9"
pb "github.com/XingfenD/yoresee_doc/pkg/gen/yoresee_doc/v1"
"github.com/sirupsen/logrus"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
"gorm.io/gorm"
)
var (
draining atomic.Bool
readyDB *gorm.DB
readyKVS *redis.Client
)
func SetDraining(v bool) {
draining.Store(v)
}
func Start(grpcPort, grpcWebPort int, db *gorm.DB, kvs *redis.Client, repos *repository.Repositories) (*http.Server, *http.Server, error) {
readyDB = db
readyKVS = kvs
allowUnauth := map[string]struct{}{
pb.AuthService_Login_FullMethodName: {},
pb.AuthService_Register_FullMethodName: {},
pb.SystemService_Health_FullMethodName: {},
pb.SystemService_SystemInfo_FullMethodName: {},
}
interceptor := UnaryAuthInterceptor(allowUnauth)
opts := []connect.HandlerOption{
connect.WithInterceptors(interceptor),
}
mux := http.NewServeMux()
registerHandlers(mux, opts, repos)
registerProbeRoutes(mux)
handler := withCORS(mux)
h2cHandler := h2c.NewHandler(handler, &http2.Server{})
grpcAddr := fmt.Sprintf(":%d", grpcPort)
grpcServer := &http.Server{Addr: grpcAddr, Handler: h2cHandler}
go func() {
if err := grpcServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
logrus.Errorf("grpc server exited unexpectedly: %v", err)
}
}()
grpcWebAddr := fmt.Sprintf(":%d", grpcWebPort)
grpcWebServer := &http.Server{Addr: grpcWebAddr, Handler: h2cHandler}
go func() {
if err := grpcWebServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
logrus.Errorf("grpc-web server exited unexpectedly: %v", err)
}
}()
return grpcServer, grpcWebServer, nil
}
func withCORS(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
setConnectCorsHeaders(w, r)
if r.Method == http.MethodOptions {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
func setConnectCorsHeaders(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
if origin == "" {
origin = "*"
}
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Credentials", "true")
w.Header().Set("Access-Control-Allow-Headers", "Accept,Accept-Language,Content-Type,Content-Length,X-Grpc-Web,X-User-Agent,Grpc-Timeout,Authorization,Connect-Protocol-Version")
w.Header().Set("Access-Control-Allow-Methods", "POST,GET,OPTIONS")
w.Header().Set("Access-Control-Expose-Headers", "Grpc-Status,Grpc-Message,Grpc-Status-Details-Bin,Connect-Protocol-Version")
}