server.go 4.7 KB

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