server.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. package std
  2. import (
  3. "net/http"
  4. "strings"
  5. "github.com/julienschmidt/httprouter"
  6. . "github.com/rpcxio/rpcx-gateway"
  7. )
  8. // Server implements gateway.HTTPServer by using julienschmidt/httprouter.
  9. type Server struct {
  10. addr string
  11. router *httprouter.Router
  12. Middleware func(next httprouter.Handle) httprouter.Handle
  13. }
  14. // New returns a server.
  15. func New(addr string) *Server {
  16. return &Server{
  17. addr: addr,
  18. }
  19. }
  20. // NewWithRouter returns a server with preconfigured router.
  21. func NewWithRouter(addr string, router *httprouter.Router) *Server {
  22. return &Server{
  23. addr: addr,
  24. router: router,
  25. }
  26. }
  27. // RegisterHandler configures the handler to handle http rpcx invoke.
  28. // It wraps ServiceHandler into httprouter.Handle.
  29. func (s *Server) RegisterHandler(base string, handler ServiceHandler) {
  30. router := s.router
  31. if router == nil {
  32. router = httprouter.New()
  33. }
  34. h := wrapServiceHandler(handler)
  35. if s.Middleware != nil {
  36. h = s.Middleware(h)
  37. }
  38. router.POST(base, h)
  39. router.GET(base, h)
  40. router.PUT(base, h)
  41. s.router = router
  42. }
  43. func wrapServiceHandler(handler ServiceHandler) httprouter.Handle {
  44. return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
  45. if r.Header.Get(XServicePath) == "" {
  46. servicePath := params.ByName("servicePath")
  47. if strings.HasPrefix(servicePath, "/") {
  48. servicePath = servicePath[1:]
  49. }
  50. r.Header.Set(XServicePath, servicePath)
  51. }
  52. servicePath := r.Header.Get(XServicePath)
  53. messageID := r.Header.Get(XMessageID)
  54. wh := w.Header()
  55. if messageID != "" {
  56. wh.Set(XMessageID, messageID)
  57. }
  58. meta, payload, err := handler(r, servicePath)
  59. for k, v := range meta {
  60. wh.Set(k, v)
  61. }
  62. if err == nil {
  63. w.Write(payload)
  64. return
  65. }
  66. rh := r.Header
  67. for k, v := range rh {
  68. if strings.HasPrefix(k, "X-RPCX-") && len(v) > 0 {
  69. wh.Set(k, v[0])
  70. }
  71. }
  72. wh.Set(XMessageStatusType, "Error")
  73. wh.Set(XErrorMessage, err.Error())
  74. return
  75. }
  76. }
  77. func (s *Server) Serve() error {
  78. return http.ListenAndServe(s.addr, s.router)
  79. }