grpc.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. package util
  2. import (
  3. "fmt"
  4. "golang.org/x/net/http2"
  5. "golang.org/x/net/http2/h2c"
  6. "net/http"
  7. "strings"
  8. "google.golang.org/grpc"
  9. )
  10. //GrpcHandlerFunc 判断请求是来源于Rpc客户端还是Restful Api的请求,根据不同的请求注册不同的ServeHTTP服务;r.ProtoMajor == 2也代表着请求必须基于HTTP/2
  11. func GrpcHandlerFunc(grpcServer *grpc.Server, otherHandler http.Handler) http.Handler {
  12. return h2c.NewHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  13. if r.ProtoMajor == 2 && strings.Contains(r.Header.Get("Content-Type"), "application/grpc") {
  14. grpcServer.ServeHTTP(w, r)
  15. } else {
  16. allowCORS(otherHandler).ServeHTTP(w, r)
  17. }
  18. }), &http2.Server{})
  19. }
  20. // allowCORS 允许跨域处理.
  21. func allowCORS(h http.Handler) http.Handler {
  22. return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  23. if origin := r.Header.Get("Origin"); origin != "" {
  24. w.Header().Set("Access-Control-Allow-Origin", origin)
  25. if r.Method == "OPTIONS" && r.Header.Get("Access-Control-Request-Method") != "" {
  26. preflightHandler(w, r)
  27. return
  28. }
  29. }
  30. h.ServeHTTP(w, r)
  31. })
  32. }
  33. func preflightHandler(w http.ResponseWriter, r *http.Request) {
  34. headers := []string{"Content-Type", "Accept", "Authorization"}
  35. w.Header().Set("Access-Control-Allow-Headers", strings.Join(headers, ","))
  36. methods := []string{"GET", "HEAD", "POST", "PUT", "DELETE"}
  37. w.Header().Set("Access-Control-Allow-Methods", strings.Join(methods, ","))
  38. fmt.Println("preflight request for:", r.URL.Path)
  39. return
  40. }