ghttp.go 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. // Package ghttp provides powerful http server and simple client implements.
  7. package ghttp
  8. import (
  9. "net/http"
  10. "reflect"
  11. "sync"
  12. "time"
  13. "github.com/gorilla/websocket"
  14. "github.com/gogf/gf/v2/container/gmap"
  15. "github.com/gogf/gf/v2/container/gtype"
  16. "github.com/gogf/gf/v2/errors/gcode"
  17. "github.com/gogf/gf/v2/errors/gerror"
  18. "github.com/gogf/gf/v2/net/goai"
  19. "github.com/gogf/gf/v2/net/gsvc"
  20. "github.com/gogf/gf/v2/os/gcache"
  21. "github.com/gogf/gf/v2/os/gctx"
  22. "github.com/gogf/gf/v2/os/gsession"
  23. "github.com/gogf/gf/v2/os/gstructs"
  24. "github.com/gogf/gf/v2/util/gtag"
  25. )
  26. type (
  27. // Server wraps the http.Server and provides more rich features.
  28. Server struct {
  29. instance string // Instance name of current HTTP server.
  30. config ServerConfig // Server configuration.
  31. plugins []Plugin // Plugin array to extend server functionality.
  32. servers []*gracefulServer // Underlying http.Server array.
  33. serverCount *gtype.Int // Underlying http.Server number for internal usage.
  34. closeChan chan struct{} // Used for underlying server closing event notification.
  35. serveTree map[string]interface{} // The route maps tree.
  36. serveCache *gcache.Cache // Server caches for internal usage.
  37. routesMap map[string][]*HandlerItem // Route map mainly for route dumps and repeated route checks.
  38. statusHandlerMap map[string][]HandlerFunc // Custom status handler map.
  39. sessionManager *gsession.Manager // Session manager.
  40. openapi *goai.OpenApiV3 // The OpenApi specification management object.
  41. serviceMu sync.Mutex // Concurrent safety for operations of attribute service.
  42. service gsvc.Service // The service for Registry.
  43. registrar gsvc.Registrar // Registrar for service register.
  44. }
  45. // Router object.
  46. Router struct {
  47. Uri string // URI.
  48. Method string // HTTP method
  49. Domain string // Bound domain.
  50. RegRule string // Parsed regular expression for route matching.
  51. RegNames []string // Parsed router parameter names.
  52. Priority int // Just for reference.
  53. }
  54. // RouterItem is just for route dumps.
  55. RouterItem struct {
  56. Handler *HandlerItem // The handler.
  57. Server string // Server name.
  58. Address string // Listening address.
  59. Domain string // Bound domain.
  60. Type HandlerType // Route handler type.
  61. Middleware string // Bound middleware.
  62. Method string // Handler method name.
  63. Route string // Route URI.
  64. Priority int // Just for reference.
  65. IsServiceHandler bool // Is service handler.
  66. }
  67. // HandlerFunc is request handler function.
  68. HandlerFunc = func(r *Request)
  69. // handlerFuncInfo contains the HandlerFunc address and its reflection type.
  70. handlerFuncInfo struct {
  71. Func HandlerFunc // Handler function address.
  72. Type reflect.Type // Reflect type information for current handler, which is used for extensions of the handler feature.
  73. Value reflect.Value // Reflect value information for current handler, which is used for extensions of the handler feature.
  74. IsStrictRoute bool // Whether strict route matching is enabled.
  75. ReqStructFields []gstructs.Field // Request struct fields.
  76. }
  77. // HandlerItem is the registered handler for route handling,
  78. // including middleware and hook functions.
  79. HandlerItem struct {
  80. // Unique handler item id mark.
  81. // Note that the handler function may be registered multiple times as different handler items,
  82. // which have different handler item id.
  83. Id int
  84. Name string // Handler name, which is automatically retrieved from runtime stack when registered.
  85. Type HandlerType // Handler type: object/handler/middleware/hook.
  86. Info handlerFuncInfo // Handler function information.
  87. InitFunc HandlerFunc // Initialization function when request enters the object (only available for object register type).
  88. ShutFunc HandlerFunc // Shutdown function when request leaves out the object (only available for object register type).
  89. Middleware []HandlerFunc // Bound middleware array.
  90. HookName HookName // Hook type name, only available for the hook type.
  91. Router *Router // Router object.
  92. Source string // Registering source file `path:line`.
  93. }
  94. // HandlerItemParsed is the item parsed from URL.Path.
  95. HandlerItemParsed struct {
  96. Handler *HandlerItem // Handler information.
  97. Values map[string]string // Router values parsed from URL.Path.
  98. }
  99. // ServerStatus is the server status enum type.
  100. ServerStatus = int
  101. // HookName is the route hook name enum type.
  102. HookName string
  103. // HandlerType is the route handler enum type.
  104. HandlerType string
  105. // Listening file descriptor mapping.
  106. // The key is either "http" or "https" and the value is its FD.
  107. listenerFdMap = map[string]string
  108. // internalPanic is the custom panic for internal usage.
  109. internalPanic string
  110. )
  111. const (
  112. // FreePortAddress marks the server listens using random free port.
  113. FreePortAddress = ":0"
  114. )
  115. const (
  116. HeaderXUrlPath = "x-url-path" // Used for custom route handler, which does not change URL.Path.
  117. HookBeforeServe HookName = "HOOK_BEFORE_SERVE" // Hook handler before route handler/file serving.
  118. HookAfterServe HookName = "HOOK_AFTER_SERVE" // Hook handler after route handler/file serving.
  119. HookBeforeOutput HookName = "HOOK_BEFORE_OUTPUT" // Hook handler before response output.
  120. HookAfterOutput HookName = "HOOK_AFTER_OUTPUT" // Hook handler after response output.
  121. ServerStatusStopped ServerStatus = 0
  122. ServerStatusRunning ServerStatus = 1
  123. DefaultServerName = "default"
  124. DefaultDomainName = "default"
  125. HandlerTypeHandler HandlerType = "handler"
  126. HandlerTypeObject HandlerType = "object"
  127. HandlerTypeMiddleware HandlerType = "middleware"
  128. HandlerTypeHook HandlerType = "hook"
  129. )
  130. const (
  131. supportedHttpMethods = "GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE"
  132. defaultMethod = "ALL"
  133. routeCacheDuration = time.Hour
  134. ctxKeyForRequest gctx.StrKey = "gHttpRequestObject"
  135. contentTypeXml = "text/xml"
  136. contentTypeHtml = "text/html"
  137. contentTypeJson = "application/json"
  138. swaggerUIPackedPath = "/goframe/swaggerui"
  139. responseHeaderTraceID = "Trace-ID"
  140. responseHeaderContentLength = "Content-Length"
  141. specialMethodNameInit = "Init"
  142. specialMethodNameShut = "Shut"
  143. specialMethodNameIndex = "Index"
  144. defaultEndpointPort = 80
  145. )
  146. const (
  147. exceptionExit internalPanic = "exit"
  148. exceptionExitAll internalPanic = "exit_all"
  149. exceptionExitHook internalPanic = "exit_hook"
  150. )
  151. var (
  152. // methodsMap stores all supported HTTP method.
  153. // It is used for quick HTTP method searching using map.
  154. methodsMap = make(map[string]struct{})
  155. // serverMapping stores more than one server instances for current processes.
  156. // The key is the name of the server, and the value is its instance.
  157. serverMapping = gmap.NewStrAnyMap(true)
  158. // serverRunning marks the running server counts.
  159. // If there is no successful server running or all servers' shutdown, this value is 0.
  160. serverRunning = gtype.NewInt()
  161. // wsUpGrader is the default up-grader configuration for websocket.
  162. wsUpGrader = websocket.Upgrader{
  163. // It does not check the origin in default, the application can do it itself.
  164. CheckOrigin: func(r *http.Request) bool {
  165. return true
  166. },
  167. }
  168. // allShutdownChan is the event for all servers have done its serving and exit.
  169. // It is used for process blocking purpose.
  170. allShutdownChan = make(chan struct{}, 1000)
  171. // serverProcessInitialized is used for lazy initialization for server.
  172. // The process can only be initialized once.
  173. serverProcessInitialized = gtype.NewBool()
  174. // gracefulEnabled is used for a graceful reload feature, which is false in default.
  175. gracefulEnabled = false
  176. // defaultValueTags are the struct tag names for default value storing.
  177. defaultValueTags = []string{gtag.DefaultShort, gtag.Default}
  178. )
  179. var (
  180. ErrNeedJsonBody = gerror.NewWithOption(gerror.Option{
  181. Text: "the request body content should be JSON format",
  182. Code: gcode.CodeInvalidRequest,
  183. })
  184. )