| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- package gateway
- import (
- "context"
- "crypto/tls"
- "fmt"
- "io"
- "io/fs"
- "mime"
- "net/http"
- "os"
- "strings"
- "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
- "github.com/osguydch/ccosproc/insecure"
- "github.com/osguydch/ccosproc/middleware"
- usersv1 "github.com/osguydch/ccosproc/proto/device/v3"
- "github.com/osguydch/ccosproc/third_party"
- "google.golang.org/grpc"
- "google.golang.org/grpc/credentials"
- "google.golang.org/grpc/grpclog"
- )
- // getOpenAPIHandler serves an OpenAPI UI.
- // Adapted from https://github.com/philips/grpc-gateway-example/blob/a269bcb5931ca92be0ceae6130ac27ae89582ecc/cmd/serve.go#L63
- func getOpenAPIHandler() http.Handler {
- mime.AddExtensionType(".svg", "image/svg+xml")
- // Use subdirectory in embedded files
- subFS, err := fs.Sub(third_party.OpenAPI, "OpenAPI")
- if err != nil {
- panic("couldn't create sub filesystem: " + err.Error())
- }
- return http.FileServer(http.FS(subFS))
- }
- // Run runs the gRPC-Gateway, dialling the provided address.
- func Run(dialAddr string, httpPort string, supprtSSL string) error {
- // Adds gRPC internal logs. This is quite verbose, so adjust as desired!
- log := grpclog.NewLoggerV2(os.Stdout, io.Discard, io.Discard)
- grpclog.SetLoggerV2(log)
- // Create a client connection to the gRPC Server we just started.
- // This is where the gRPC-Gateway proxies the requests.
- conn, err := grpc.DialContext(
- context.Background(),
- dialAddr,
- grpc.WithTransportCredentials(credentials.NewClientTLSFromCert(insecure.CertPool, "")),
- //grpc.WithInsecure(),
- grpc.WithBlock(),
- )
- if err != nil {
- return fmt.Errorf("failed to dial server: %w", err)
- }
- gwmux := runtime.NewServeMux()
- err = usersv1.RegisterDeviceHandler(context.Background(), gwmux, conn)
- if err != nil {
- return fmt.Errorf("failed to register gateway: %w", err)
- }
- // 预先创建CORS包装的handlers,避免每次请求重复创建
- apiHandler := middleware.Cors(gwmux)
- moduleHandler := middleware.Cors(http.StripPrefix("/module/", http.FileServer(http.Dir("./DriverDefine"))))
- dataHandler := middleware.Cors(http.StripPrefix("/Data/", http.FileServer(http.Dir("./RawData"))))
- openAPIHandler := getOpenAPIHandler()
- gatewayAddr := "0.0.0.0:" + httpPort
- gwServer := &http.Server{
- Addr: gatewayAddr,
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- if strings.HasPrefix(r.URL.Path, "/api") {
- log.Info("Serving device apis", r.URL.Path)
- apiHandler.ServeHTTP(w, r)
- return
- }
- if strings.HasPrefix(r.URL.Path, "/module") {
- log.Info("Serving module definition", r.URL.Path)
- moduleHandler.ServeHTTP(w, r)
- return
- }
- if strings.HasPrefix(r.URL.Path, "/Data") {
- log.Info("Serving data file", r.URL.Path)
- dataHandler.ServeHTTP(w, r)
- return
- }
- openAPIHandler.ServeHTTP(w, r)
- }),
- }
- if supprtSSL != "ON" {
- log.Info("Serving gRPC-Gateway and OpenAPI Documentation on http://", gatewayAddr)
- return fmt.Errorf("serving gRPC-Gateway server: %w", gwServer.ListenAndServe())
- }
- gwServer.TLSConfig = &tls.Config{
- Certificates: []tls.Certificate{insecure.Cert},
- }
- log.Info("Serving gRPC-Gateway and OpenAPI Documentation on https://", gatewayAddr)
- return fmt.Errorf("serving gRPC-Gateway server: %w", gwServer.ListenAndServeTLS("", ""))
- }
|