server.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. package http
  2. import (
  3. "context"
  4. "git.nspix.com/golang/micro/gateway/http/router"
  5. "net"
  6. "net/http"
  7. "sync"
  8. )
  9. var (
  10. contextPool sync.Pool
  11. )
  12. type contextRouteKey struct{}
  13. type HandleFunc func(ctx *Context) (err error)
  14. type Middleware func(next HandleFunc) HandleFunc
  15. type Node struct {
  16. Method string
  17. Path string
  18. Handle HandleFunc
  19. }
  20. type Server struct {
  21. svr *http.Server
  22. middleware []Middleware
  23. keepAlive bool
  24. isSetKeepAlive bool
  25. router *router.Router
  26. }
  27. func getContext() *Context {
  28. if v := contextPool.Get(); v != nil {
  29. return v.(*Context)
  30. }
  31. return &Context{}
  32. }
  33. func releaseContext(c *Context) {
  34. contextPool.Put(c)
  35. }
  36. func (r *Server) Group(prefix string, nodes []Node, middleware ...Middleware) {
  37. for _, node := range nodes {
  38. r.Handle(node.Method, prefix+node.Path, node.Handle, middleware...)
  39. }
  40. }
  41. func (r *Server) Handler(method, path string, h http.Handler) {
  42. r.router.Handler(method, path, h)
  43. }
  44. func (r *Server) Handle(method string, path string, h HandleFunc, middleware ...Middleware) {
  45. r.router.Handle(method, path, func(writer http.ResponseWriter, request *http.Request, params router.Params) {
  46. ctx := getContext()
  47. ps := make(map[string]string)
  48. for _, v := range params {
  49. ps[v.Key] = v.Value
  50. }
  51. ctx.Reset(request, writer, ps)
  52. for i := len(r.middleware) - 1; i >= 0; i-- {
  53. h = r.middleware[i](h)
  54. }
  55. for i := len(middleware) - 1; i >= 0; i-- {
  56. h = middleware[i](h)
  57. }
  58. if err := h(ctx); err != nil {
  59. writer.WriteHeader(http.StatusInternalServerError)
  60. }
  61. releaseContext(ctx)
  62. })
  63. }
  64. func (r *Server) Use(ms ...Middleware) {
  65. r.middleware = append(r.middleware, ms...)
  66. }
  67. func (r *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) {
  68. if req.Method == http.MethodOptions {
  69. res.Header().Add("Vary", "Origin")
  70. res.Header().Add("Vary", "Access-Control-Request-Method")
  71. res.Header().Add("Vary", "Access-Control-Request-Headers")
  72. res.Header().Set("Access-Control-Allow-Origin", "*")
  73. res.Header().Set("Access-Control-Allow-Credentials", "true")
  74. res.Header().Set("Access-Control-Allow-Methods", "GET,HEAD,PUT,PATCH,POST,DELETE")
  75. h := req.Header.Get("Access-Control-Request-Headers")
  76. if h != "" {
  77. res.Header().Set("Access-Control-Allow-Headers", h)
  78. }
  79. res.WriteHeader(http.StatusNoContent)
  80. return
  81. } else {
  82. res.Header().Add("Vary", "Origin")
  83. res.Header().Set("Access-Control-Allow-Origin", "*")
  84. res.Header().Set("Access-Control-Allow-Credentials", "true")
  85. h := req.Header.Get("Access-Control-Request-Headers")
  86. if h != "" {
  87. res.Header().Set("Access-Control-Allow-Headers", h)
  88. }
  89. r.router.ServeHTTP(res, req)
  90. }
  91. }
  92. func (r *Server) Server() *http.Server {
  93. return r.svr
  94. }
  95. func (r *Server) SetKeepAlivesEnabled(enable bool) {
  96. r.isSetKeepAlive = true
  97. r.keepAlive = enable
  98. }
  99. func (r *Server) ListenAndServe(addr string) (err error) {
  100. r.svr = &http.Server{
  101. Addr: addr,
  102. Handler: r,
  103. }
  104. if r.isSetKeepAlive {
  105. r.svr.SetKeepAlivesEnabled(r.keepAlive)
  106. }
  107. return r.svr.ListenAndServe()
  108. }
  109. func (r *Server) Serve(l net.Listener) (err error) {
  110. r.svr = &http.Server{
  111. Handler: r,
  112. }
  113. if r.isSetKeepAlive {
  114. r.svr.SetKeepAlivesEnabled(r.keepAlive)
  115. }
  116. return r.svr.Serve(l)
  117. }
  118. func (r *Server) Shutdown(ctx context.Context) (err error) {
  119. if r.svr != nil {
  120. return r.svr.Shutdown(ctx)
  121. }
  122. return
  123. }
  124. func New() *Server {
  125. return &Server{
  126. router: router.New(),
  127. }
  128. }
  129. func WithContext(ctx context.Context, route *Server) context.Context {
  130. return context.WithValue(ctx, contextRouteKey{}, route)
  131. }
  132. func FromContext(ctx context.Context) *Server {
  133. if v := ctx.Value(contextRouteKey{}); v != nil {
  134. return v.(*Server)
  135. }
  136. return nil
  137. }