2021-01-17 21:46:25 +08:00
|
|
|
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
2018-01-03 10:38:53 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2018-01-03 10:38:53 +08:00
|
|
|
|
2019-06-18 20:58:47 +08:00
|
|
|
// Package ghttp provides powerful http server and simple client implements.
|
2018-01-03 10:38:53 +08:00
|
|
|
package ghttp
|
2020-11-08 15:44:04 +08:00
|
|
|
|
|
|
|
import (
|
2021-11-13 23:23:55 +08:00
|
|
|
"net/http"
|
|
|
|
"reflect"
|
|
|
|
"time"
|
|
|
|
|
2021-10-11 21:41:56 +08:00
|
|
|
"github.com/gogf/gf/v2/container/gmap"
|
|
|
|
"github.com/gogf/gf/v2/container/gtype"
|
|
|
|
"github.com/gogf/gf/v2/os/gcache"
|
|
|
|
"github.com/gogf/gf/v2/os/gsession"
|
|
|
|
"github.com/gogf/gf/v2/protocol/goai"
|
2020-11-08 15:44:04 +08:00
|
|
|
"github.com/gorilla/websocket"
|
|
|
|
)
|
|
|
|
|
|
|
|
type (
|
2021-06-26 11:18:44 +08:00
|
|
|
// Server wraps the http.Server and provides more rich features.
|
2020-11-08 15:44:04 +08:00
|
|
|
Server struct {
|
|
|
|
name string // Unique name for instance management.
|
|
|
|
config ServerConfig // Configuration.
|
2021-08-20 23:15:48 +08:00
|
|
|
plugins []Plugin // Plugin array to extend server functionality.
|
2020-11-08 15:44:04 +08:00
|
|
|
servers []*gracefulServer // Underlying http.Server array.
|
|
|
|
serverCount *gtype.Int // Underlying http.Server count.
|
|
|
|
closeChan chan struct{} // Used for underlying server closing event notification.
|
|
|
|
serveTree map[string]interface{} // The route map tree.
|
2021-08-20 23:15:48 +08:00
|
|
|
serveCache *gcache.Cache // Server caches for internal usage.
|
2020-11-08 15:44:04 +08:00
|
|
|
routesMap map[string][]registeredRouteItem // Route map mainly for route dumps and repeated route checks.
|
2020-11-25 16:37:41 +08:00
|
|
|
statusHandlerMap map[string][]HandlerFunc // Custom status handler map.
|
2020-11-08 15:44:04 +08:00
|
|
|
sessionManager *gsession.Manager // Session manager.
|
2021-10-02 22:34:39 +08:00
|
|
|
openapi *goai.OpenApiV3 // The OpenApi specification management object.
|
2020-11-08 15:44:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Router object.
|
|
|
|
Router struct {
|
|
|
|
Uri string // URI.
|
|
|
|
Method string // HTTP method
|
|
|
|
Domain string // Bound domain.
|
|
|
|
RegRule string // Parsed regular expression for route matching.
|
|
|
|
RegNames []string // Parsed router parameter names.
|
|
|
|
Priority int // Just for reference.
|
|
|
|
}
|
|
|
|
|
2021-06-26 11:18:44 +08:00
|
|
|
// RouterItem is just for route dumps.
|
2020-11-08 15:44:04 +08:00
|
|
|
RouterItem struct {
|
2021-10-02 22:34:39 +08:00
|
|
|
Handler *handlerItem // The handler.
|
2020-11-08 15:44:04 +08:00
|
|
|
Server string // Server name.
|
|
|
|
Address string // Listening address.
|
|
|
|
Domain string // Bound domain.
|
2021-10-06 14:22:58 +08:00
|
|
|
Type string // Router type.
|
2020-11-08 15:44:04 +08:00
|
|
|
Middleware string // Bound middleware.
|
|
|
|
Method string // Handler method name.
|
|
|
|
Route string // Route URI.
|
|
|
|
Priority int // Just for reference.
|
|
|
|
IsServiceHandler bool // Is service handler.
|
|
|
|
}
|
|
|
|
|
2021-07-13 23:01:31 +08:00
|
|
|
// HandlerFunc is request handler function.
|
|
|
|
HandlerFunc = func(r *Request)
|
|
|
|
|
2021-10-02 22:34:39 +08:00
|
|
|
// handlerFuncInfo contains the HandlerFunc address and its reflection type.
|
2021-07-13 23:01:31 +08:00
|
|
|
handlerFuncInfo struct {
|
|
|
|
Func HandlerFunc // Handler function address.
|
|
|
|
Type reflect.Type // Reflect type information for current handler, which is used for extension of handler feature.
|
|
|
|
Value reflect.Value // Reflect value information for current handler, which is used for extension of handler feature.
|
|
|
|
}
|
|
|
|
|
2020-11-08 15:44:04 +08:00
|
|
|
// handlerItem is the registered handler for route handling,
|
|
|
|
// including middleware and hook functions.
|
|
|
|
handlerItem struct {
|
2021-07-30 15:15:44 +08:00
|
|
|
Id int // Unique handler item id mark.
|
|
|
|
Name string // Handler name, which is automatically retrieved from runtime stack when registered.
|
2021-10-06 14:22:58 +08:00
|
|
|
Type string // Handler type: object/handler/middleware/hook.
|
2021-07-30 15:15:44 +08:00
|
|
|
Info handlerFuncInfo // Handler function information.
|
|
|
|
InitFunc HandlerFunc // Initialization function when request enters the object (only available for object register type).
|
|
|
|
ShutFunc HandlerFunc // Shutdown function when request leaves out the object (only available for object register type).
|
|
|
|
Middleware []HandlerFunc // Bound middleware array.
|
|
|
|
HookName string // Hook type name, only available for hook type.
|
|
|
|
Router *Router // Router object.
|
|
|
|
Source string // Registering source file `path:line`.
|
2020-11-08 15:44:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// handlerParsedItem is the item parsed from URL.Path.
|
|
|
|
handlerParsedItem struct {
|
2021-07-19 20:06:44 +08:00
|
|
|
Handler *handlerItem // Handler information.
|
|
|
|
Values map[string]string // Router values parsed from URL.Path.
|
2020-11-08 15:44:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// registeredRouteItem stores the information of the router and is used for route map.
|
|
|
|
registeredRouteItem struct {
|
2021-07-19 20:06:44 +08:00
|
|
|
Source string // Source file path and its line number.
|
|
|
|
Handler *handlerItem // Handler object.
|
2020-11-08 15:44:04 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Listening file descriptor mapping.
|
|
|
|
// The key is either "http" or "https" and the value is its FD.
|
|
|
|
listenerFdMap = map[string]string
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2020-12-14 13:26:48 +08:00
|
|
|
HookBeforeServe = "HOOK_BEFORE_SERVE"
|
|
|
|
HookAfterServe = "HOOK_AFTER_SERVE"
|
|
|
|
HookBeforeOutput = "HOOK_BEFORE_OUTPUT"
|
|
|
|
HookAfterOutput = "HOOK_AFTER_OUTPUT"
|
|
|
|
ServerStatusStopped = 0
|
|
|
|
ServerStatusRunning = 1
|
2021-09-19 10:01:09 +08:00
|
|
|
DefaultServerName = "default"
|
|
|
|
DefaultDomainName = "default"
|
2021-10-06 14:22:58 +08:00
|
|
|
HandlerTypeHandler = "handler"
|
|
|
|
HandlerTypeObject = "object"
|
|
|
|
HandlerTypeMiddleware = "middleware"
|
|
|
|
HandlerTypeHook = "hook"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
supportedHttpMethods = "GET,PUT,POST,DELETE,PATCH,HEAD,CONNECT,OPTIONS,TRACE"
|
|
|
|
defaultMethod = "ALL"
|
|
|
|
exceptionExit = "exit"
|
|
|
|
exceptionExitAll = "exit_all"
|
|
|
|
exceptionExitHook = "exit_hook"
|
|
|
|
routeCacheDuration = time.Hour
|
|
|
|
methodNameInit = "Init"
|
|
|
|
methodNameShut = "Shut"
|
|
|
|
ctxKeyForRequest = "gHttpRequestObject"
|
2021-12-17 17:42:18 +08:00
|
|
|
contentTypeXml = "text/xml"
|
|
|
|
contentTypeHtml = "text/html"
|
|
|
|
contentTypeJson = "application/json"
|
2021-10-06 14:22:58 +08:00
|
|
|
swaggerUIPackedPath = "/goframe/swaggerui"
|
2020-11-08 15:44:04 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
// methodsMap stores all supported HTTP method,
|
|
|
|
// it is used for quick HTTP method searching using map.
|
|
|
|
methodsMap = make(map[string]struct{})
|
|
|
|
|
|
|
|
// serverMapping stores more than one server instances for current process.
|
|
|
|
// The key is the name of the server, and the value is its instance.
|
|
|
|
serverMapping = gmap.NewStrAnyMap(true)
|
|
|
|
|
|
|
|
// serverRunning marks the running server count.
|
2021-08-20 23:15:48 +08:00
|
|
|
// If there is no successful server running or all servers' shutdown, this value is 0.
|
2020-11-08 15:44:04 +08:00
|
|
|
serverRunning = gtype.NewInt()
|
|
|
|
|
|
|
|
// wsUpGrader is the default up-grader configuration for websocket.
|
|
|
|
wsUpGrader = websocket.Upgrader{
|
|
|
|
// It does not check the origin in default, the application can do it itself.
|
|
|
|
CheckOrigin: func(r *http.Request) bool {
|
|
|
|
return true
|
|
|
|
},
|
|
|
|
}
|
|
|
|
// allDoneChan is the event for all server have done its serving and exit.
|
|
|
|
// It is used for process blocking purpose.
|
|
|
|
allDoneChan = make(chan struct{}, 1000)
|
|
|
|
|
|
|
|
// serverProcessInitialized is used for lazy initialization for server.
|
|
|
|
// The process can only be initialized once.
|
|
|
|
serverProcessInitialized = gtype.NewBool()
|
|
|
|
|
|
|
|
// gracefulEnabled is used for graceful reload feature, which is false in default.
|
|
|
|
gracefulEnabled = false
|
|
|
|
|
|
|
|
// defaultValueTags is the struct tag names for default value storing.
|
|
|
|
defaultValueTags = []string{"d", "default"}
|
|
|
|
)
|