server.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package gin
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/gin-contrib/cors"
  6. "github.com/gin-gonic/gin"
  7. . "github.com/rpcxio/rpcx-gateway"
  8. )
  9. type Server struct {
  10. addr string
  11. g *gin.Engine
  12. }
  13. // New returns a server.
  14. func New(addr string) *Server {
  15. return &Server{
  16. addr: addr,
  17. }
  18. }
  19. // NewWithGin returns a server with preconfigured gin.
  20. func NewWithGin(addr string, g *gin.Engine) *Server {
  21. return &Server{
  22. addr: addr,
  23. g: g,
  24. }
  25. }
  26. // RegisterHandler configures the handler to handle http rpcx invoke.
  27. // It wraps ServiceHandler into httprouter.Handle.
  28. func (s *Server) RegisterHandler(base string, handler ServiceHandler) {
  29. g := s.g
  30. if g == nil {
  31. gin.SetMode(gin.ReleaseMode) // 设备为生产模式 add by sunmiao
  32. g = gin.Default()
  33. // 添加CORS处理 add by sunmiao
  34. config := cors.DefaultConfig()
  35. config.AllowAllOrigins = true
  36. config.AllowHeaders = []string{"Origin", "Content-Length", "Content-Type", "Authorization","Tenant","X-RPCX-SerializeType", "X-RPCX-ServiceMethod", "X-RPCX-ServicePath", "X-RPCX-Meta"}
  37. g.Use(cors.New(config))
  38. }
  39. h := wrapServiceHandler(handler)
  40. g.POST(base, h)
  41. // 只开放POST edit by sunmiao
  42. //g.GET(base, h)
  43. //g.PUT(base, h)
  44. s.g = g
  45. }
  46. func wrapServiceHandler(handler ServiceHandler) gin.HandlerFunc {
  47. return func(ctx *gin.Context) {
  48. r := ctx.Request
  49. w := ctx.Writer
  50. if r.Header.Get(XServicePath) == "" {
  51. servicePath := ctx.Param("servicePath")
  52. if strings.HasPrefix(servicePath, "/") {
  53. servicePath = servicePath[1:]
  54. }
  55. r.Header.Set(XServicePath, servicePath)
  56. }
  57. servicePath := r.Header.Get(XServicePath)
  58. messageID := r.Header.Get(XMessageID)
  59. wh := w.Header()
  60. if messageID != "" {
  61. wh.Set(XMessageID, messageID)
  62. }
  63. meta, payload, err := handler(r, servicePath)
  64. for k, v := range meta {
  65. wh.Set(k, v)
  66. }
  67. if err == nil {
  68. ctx.Data(http.StatusOK, "application/octet-stream", payload)
  69. return
  70. }
  71. rh := r.Header
  72. for k, v := range rh {
  73. if strings.HasPrefix(k, "X-RPCX-") && len(v) > 0 {
  74. wh.Set(k, v[0])
  75. }
  76. }
  77. wh.Set(XMessageStatusType, "Error")
  78. wh.Set(XErrorMessage, err.Error())
  79. ctx.String(http.StatusOK, err.Error())
  80. }
  81. }
  82. func (s *Server) Serve() error {
  83. return s.g.Run(s.addr)
  84. }