package util import ( "fmt" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" "net/http" "strings" "google.golang.org/grpc" ) //GrpcHandlerFunc 判断请求是来源于Rpc客户端还是Restful Api的请求,根据不同的请求注册不同的ServeHTTP服务;r.ProtoMajor == 2也代表着请求必须基于HTTP/2 func GrpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler { return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") { grpcServer.ServeHTTP(w, r) } else { allowCORS(otherHandler).ServeHTTP(w, r) } }), &http2.Server{}) } // allowCORS 允许跨域处理. func allowCORS(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if origin := r.Header.Get("Origin"); origin != "" { w.Header().Set("Access-Control-Allow-Origin", origin) if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" { preflightHandler(w, r) return } } h.ServeHTTP(w, r) }) } func preflightHandler(w http.ResponseWriter, r *http.Request) { headers := []string{"Content-Type", "Accept", "Authorization"} w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ",")) methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"} w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ",")) fmt.Println("preflight request for:", r.URL.Path) return }