diff --git a/config/configs.go b/config/configs.go
index be9c389..857dee8 100644
--- a/config/configs.go
+++ b/config/configs.go
@@ -41,16 +41,17 @@ type (
}
ServerNode struct {
- EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启
- EnabledGzip bool `xml:"enabledgzip,attr"` //是否启用gzip
- EnabledAutoHEAD bool `xml:"enabledautohead,attr"` //设置是否自动启用Head路由,若设置该项,则会为除Websocket\HEAD外所有路由方式默认添加HEAD路由,默认不开启
- EnabledAutoCORS bool `xml:"enabledautocors,attr"` //设置是否自动跨域支持,若设置,默认“GET, POST, PUT, DELETE, OPTIONS”全部请求均支持跨域
- EnabledIgnoreFavicon bool `xml:"enabledignorefavicon,attr"` //设置是否忽略favicon.ico请求,若设置,网站将把所有favicon.ico请求直接空返回
- Port int `xml:"port,attr"` //端口
- EnabledTLS bool `xml:"enabledtls,attr"` //是否启用TLS模式
- TLSCertFile string `xml:"tlscertfile,attr"` //TLS模式下Certificate证书文件地址
- TLSKeyFile string `xml:"tlskeyfile,attr"` //TLS模式下秘钥文件地址
- IndexPage string `xml:"indexpage,attr"` //默认index页面
+ EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启
+ EnabledGzip bool `xml:"enabledgzip,attr"` //是否启用gzip
+ EnabledAutoHEAD bool `xml:"enabledautohead,attr"` //设置是否自动启用Head路由,若设置该项,则会为除Websocket\HEAD外所有路由方式默认添加HEAD路由,默认不开启
+ EnabledAutoCORS bool `xml:"enabledautocors,attr"` //设置是否自动跨域支持,若设置,默认“GET, POST, PUT, DELETE, OPTIONS”全部请求均支持跨域
+ EnabledIgnoreFavicon bool `xml:"enabledignorefavicon,attr"` //设置是否忽略favicon.ico请求,若设置,网站将把所有favicon.ico请求直接空返回
+ Port int `xml:"port,attr"` //端口
+ EnabledTLS bool `xml:"enabledtls,attr"` //是否启用TLS模式
+ TLSCertFile string `xml:"tlscertfile,attr"` //TLS模式下Certificate证书文件地址
+ TLSKeyFile string `xml:"tlskeyfile,attr"` //TLS模式下秘钥文件地址
+ IndexPage string `xml:"indexpage,attr"` //默认index页面
+ EnabledDetailRequestData bool `xml:"enableddetailrequestdata,attr"` //设置状态数据是否启用详细页面统计,默认不启用,请特别对待,如果站点url过多,会导致数据量过大
}
SessionNode struct {
diff --git a/context.go b/context.go
index f673ad3..622e46a 100644
--- a/context.go
+++ b/context.go
@@ -254,7 +254,7 @@ func (ctx *HttpContext) Session() (state *session.SessionState) {
//return nil, errors.New("no effective http-server")
panic("no effective http-server")
}
- if !ctx.httpServer.SessionConfig.EnabledSession {
+ if !ctx.httpServer.SessionConfig().EnabledSession {
//return nil, errors.New("http-server not enabled session")
panic("http-server not enabled session")
}
diff --git a/core/state.go b/core/state.go
index 8958dd6..f0af9cc 100644
--- a/core/state.go
+++ b/core/state.go
@@ -2,6 +2,7 @@ package core
import (
"github.com/devfeel/dotweb/framework/json"
+ "net/http"
"strconv"
"strings"
"sync"
@@ -20,18 +21,18 @@ const (
func init() {
GlobalState = &ServerStateInfo{
- ServerStartTime: time.Now(),
- TotalRequestCount: 0,
- TotalErrorCount: 0,
- IntervalRequestData: NewItemContext(),
- DetailRequestPageData: NewItemContext(),
- IntervalErrorData: NewItemContext(),
- DetailErrorPageData: NewItemContext(),
- DetailErrorData: NewItemContext(),
- DetailHTTPCodeData: NewItemContext(),
- dataChan_Request: make(chan *RequestInfo, 1000),
- dataChan_Error: make(chan *ErrorInfo, 1000),
- dataChan_HttpCode: make(chan *HttpCodeInfo, 1000),
+ ServerStartTime: time.Now(),
+ TotalRequestCount: 0,
+ TotalErrorCount: 0,
+ IntervalRequestData: NewItemContext(),
+ DetailRequestUrlData: NewItemContext(),
+ IntervalErrorData: NewItemContext(),
+ DetailErrorPageData: NewItemContext(),
+ DetailErrorData: NewItemContext(),
+ DetailHTTPCodeData: NewItemContext(),
+ dataChan_Request: make(chan *RequestInfo, 1000),
+ dataChan_Error: make(chan *ErrorInfo, 1000),
+ dataChan_HttpCode: make(chan *HttpCodeInfo, 1000),
infoPool: &pool{
requestInfo: sync.Pool{
New: func() interface{} {
@@ -63,8 +64,9 @@ type pool struct {
//http request count info
type RequestInfo struct {
- Url string
- Num uint64
+ Url string
+ Code int
+ Num uint64
}
//error count info
@@ -85,12 +87,14 @@ type HttpCodeInfo struct {
type ServerStateInfo struct {
//服务启动时间
ServerStartTime time.Time
+ //是否启用详细请求数据统计 fixed #63 状态数据,当url较多时,导致内存占用过大
+ EnabledDetailRequestData bool
//该运行期间总访问次数
TotalRequestCount uint64
//单位时间内请求数据 - 按分钟为单位
IntervalRequestData *ItemContext
//明细请求页面数据 - 以不带参数的访问url为key
- DetailRequestPageData *ItemContext
+ DetailRequestUrlData *ItemContext
//该运行期间异常次数
TotalErrorCount uint64
//单位时间内异常次数 - 按分钟为单位
@@ -122,9 +126,9 @@ func (state *ServerStateInfo) ShowHtmlData() string {
data += "IntervalRequestData : " + jsonutil.GetJsonString(state.IntervalRequestData.GetCurrentMap())
state.IntervalRequestData.RUnlock()
data += "
"
- state.DetailRequestPageData.RLock()
- data += "DetailRequestPageData : " + jsonutil.GetJsonString(state.DetailRequestPageData.GetCurrentMap())
- state.DetailRequestPageData.RUnlock()
+ state.DetailRequestUrlData.RLock()
+ data += "DetailRequestUrlData : " + jsonutil.GetJsonString(state.DetailRequestUrlData.GetCurrentMap())
+ state.DetailRequestUrlData.RUnlock()
data += "
"
state.IntervalErrorData.RLock()
data += "IntervalErrorData : " + jsonutil.GetJsonString(state.IntervalErrorData.GetCurrentMap())
@@ -156,20 +160,13 @@ func (state *ServerStateInfo) QueryIntervalErrorData(queryKey string) uint64 {
}
//AddRequestCount 增加请求数
-func (state *ServerStateInfo) AddRequestCount(page string, num uint64) uint64 {
+func (state *ServerStateInfo) AddRequestCount(page string, code int, num uint64) uint64 {
if strings.Index(page, "/dotweb/") != 0 {
atomic.AddUint64(&state.TotalRequestCount, num)
- state.addRequestData(page, num)
- }
- return state.TotalRequestCount
-}
-
-//AddHttpCodeCount 增加Http状态码数据
-func (state *ServerStateInfo) AddTTPCodeCount(page string, code int, num uint64) uint64 {
- if strings.Index(page, "/dotweb/") != 0 {
+ state.addRequestData(page, code, num)
state.addHTTPCodeData(page, code, num)
}
- return state.TotalErrorCount
+ return state.TotalRequestCount
}
//AddErrorCount 增加错误数
@@ -179,10 +176,11 @@ func (state *ServerStateInfo) AddErrorCount(page string, err error, num uint64)
return state.TotalErrorCount
}
-func (state *ServerStateInfo) addRequestData(page string, num uint64) {
+func (state *ServerStateInfo) addRequestData(page string, code int, num uint64) {
//get from pool
info := state.infoPool.requestInfo.Get().(*RequestInfo)
info.Url = page
+ info.Code = code
info.Num = num
state.dataChan_Request <- info
}
@@ -211,14 +209,19 @@ func (state *ServerStateInfo) handleInfo() {
select {
case info := <-state.dataChan_Request:
{
- //set detail page data
- key := strings.ToLower(info.Url)
- val := state.DetailRequestPageData.GetUInt64(key)
- state.DetailRequestPageData.Set(key, val+info.Num)
-
+ //fixed #63 状态数据,当url较多时,导致内存占用过大
+ if state.EnabledDetailRequestData {
+ //ignore 404 request
+ if info.Code != http.StatusNotFound {
+ //set detail url data
+ key := strings.ToLower(info.Url)
+ val := state.DetailRequestUrlData.GetUInt64(key)
+ state.DetailRequestUrlData.Set(key, val+info.Num)
+ }
+ }
//set interval data
- key = time.Now().Format(minuteTimeLayout)
- val = state.IntervalRequestData.GetUInt64(key)
+ key := time.Now().Format(minuteTimeLayout)
+ val := state.IntervalRequestData.GetUInt64(key)
state.IntervalRequestData.Set(key, val+info.Num)
//put info obj
diff --git a/dotweb.go b/dotweb.go
index bdd12d0..21e5d56 100644
--- a/dotweb.go
+++ b/dotweb.go
@@ -24,20 +24,23 @@ import (
type (
DotWeb struct {
- HttpServer *HttpServer
- cache cache.Cache
- OfflineServer servers.Server
- Config *config.Config
- Middlewares []Middleware
- ExceptionHandler ExceptionHandle
- NotFoundHandler NotFoundHandle
- AppContext *core.ItemContext
- middlewareMap map[string]MiddlewareFunc
- middlewareMutex *sync.RWMutex
+ HttpServer *HttpServer
+ cache cache.Cache
+ OfflineServer servers.Server
+ Config *config.Config
+ Middlewares []Middleware
+ ExceptionHandler ExceptionHandle
+ NotFoundHandler NotFoundHandle
+ MethodNotAllowedHandler MethodNotAllowedHandle
+ AppContext *core.ItemContext
+ middlewareMap map[string]MiddlewareFunc
+ middlewareMutex *sync.RWMutex
}
ExceptionHandle func(Context, error)
- NotFoundHandle func(http.ResponseWriter, *http.Request)
+ //fixed for #64 增加MethodNotAllowed自定义处理
+ MethodNotAllowedHandle func(Context)
+ NotFoundHandle func(Context)
// Handle is a function that can be registered to a route to handle HTTP
// requests. Like http.HandlerFunc, but has a special parameter Context contain all request and response data.
@@ -153,6 +156,11 @@ func (app *DotWeb) SetNotFoundHandle(handler NotFoundHandle) {
app.NotFoundHandler = handler
}
+// SetMethodNotAllowedHandle set custom 405 handler
+func (app *DotWeb) SetMethodNotAllowedHandle(handler MethodNotAllowedHandle) {
+ app.MethodNotAllowedHandler = handler
+}
+
// SetPProfConfig set pprofserver config, default is disable
// and don't use same port with StartServer
func (app *DotWeb) SetPProfConfig(enabledPProf bool, httpport int) {
@@ -180,6 +188,59 @@ func (app *DotWeb) SetEnabledLog(enabledLog bool) {
func (app *DotWeb) SetConfig(config *config.Config) error {
app.Config = config
+ return nil
+}
+
+// StartServer start server with http port
+// if config the pprof, will be start pprof server
+func (app *DotWeb) StartServer(httpport int) error {
+ addr := ":" + strconv.Itoa(httpport)
+ return app.ListenAndServe(addr)
+}
+
+// Start start app server with set config
+// If an exception occurs, will be return it
+// if no set Server.Port, will be use DefaultHttpPort
+func (app *DotWeb) Start() error {
+ if app.Config == nil {
+ return errors.New("no config set!")
+ }
+ //start server
+ port := app.Config.Server.Port
+ if port <= 0 {
+ port = DefaultHttpPort
+ }
+ return app.StartServer(port)
+}
+
+// MustStart start app server with set config
+// If an exception occurs, will be panic it
+// if no set Server.Port, will be use DefaultHttpPort
+func (app *DotWeb) MustStart() {
+ err := app.Start()
+ if err != nil {
+ panic(err)
+ }
+}
+
+// ListenAndServe start server with addr
+// not support pprof server auto start
+func (app *DotWeb) ListenAndServe(addr string) error {
+ app.initAppConfig()
+ app.initServerEnvironment()
+ app.initInnerRouter()
+ if app.HttpServer.ServerConfig().EnabledTLS {
+ err := app.HttpServer.ListenAndServeTLS(addr, app.HttpServer.ServerConfig().TLSCertFile, app.HttpServer.ServerConfig().TLSKeyFile)
+ return err
+ }
+ err := app.HttpServer.ListenAndServe(addr)
+ return err
+
+}
+
+// init App Config
+func (app *DotWeb) initAppConfig() {
+ config := app.Config
//log config
if config.App.LogPath != "" {
logger.SetLogPath(config.App.LogPath)
@@ -212,6 +273,11 @@ func (app *DotWeb) SetConfig(config *config.Config) error {
app.HttpServer.SetSessionConfig(session.NewStoreConfig(config.Session.SessionMode, config.Session.Timeout, config.Session.ServerIP))
}
+ //设置启用详细请求数据统计
+ if config.Server.EnabledDetailRequestData {
+ core.GlobalState.EnabledDetailRequestData = config.Server.EnabledDetailRequestData
+ }
+
//register app's middleware
for _, m := range config.Middlewares {
if m.IsUse {
@@ -265,53 +331,6 @@ func (app *DotWeb) SetConfig(config *config.Config) error {
}
}
}
- return nil
-}
-
-// StartServer start server with http port
-// if config the pprof, will be start pprof server
-func (app *DotWeb) StartServer(httpport int) error {
- addr := ":" + strconv.Itoa(httpport)
- return app.ListenAndServe(addr)
-}
-
-// Start start app server with set config
-// If an exception occurs, will be return it
-// if no set Server.Port, will be use DefaultHttpPort
-func (app *DotWeb) Start() error {
- if app.Config == nil {
- return errors.New("no config set!")
- }
- //start server
- port := app.Config.Server.Port
- if port <= 0 {
- port = DefaultHttpPort
- }
- return app.StartServer(port)
-}
-
-// MustStart start app server with set config
-// If an exception occurs, will be panic it
-// if no set Server.Port, will be use DefaultHttpPort
-func (app *DotWeb) MustStart() {
- err := app.Start()
- if err != nil {
- panic(err)
- }
-}
-
-// ListenAndServe start server with addr
-// not support pprof server auto start
-func (app *DotWeb) ListenAndServe(addr string) error {
- app.initServerEnvironment()
- app.initInnerRouter()
- if app.HttpServer.ServerConfig.EnabledTLS {
- err := app.HttpServer.ListenAndServeTLS(addr, app.HttpServer.ServerConfig.TLSCertFile, app.HttpServer.ServerConfig.TLSKeyFile)
- return err
- }
- err := app.HttpServer.ListenAndServe(addr)
- return err
-
}
// init inner routers
@@ -325,14 +344,23 @@ func (app *DotWeb) initInnerRouter() {
gInner.GET("/query/:key", showQuery)
}
+// init Server Environment
func (app *DotWeb) initServerEnvironment() {
if app.ExceptionHandler == nil {
app.SetExceptionHandle(app.DefaultHTTPErrorHandler)
}
+ if app.NotFoundHandler == nil {
+ app.SetNotFoundHandle(app.DefaultNotFoundHandler)
+ }
+
+ if app.MethodNotAllowedHandler == nil {
+ app.SetMethodNotAllowedHandle(app.DefaultMethodNotAllowedHandler)
+ }
+
//init session manager
- if app.HttpServer.SessionConfig.EnabledSession {
- if app.HttpServer.SessionConfig.SessionMode == "" {
+ if app.HttpServer.SessionConfig().EnabledSession {
+ if app.HttpServer.SessionConfig().SessionMode == "" {
//panic("no set SessionConfig, but set enabledsession true")
logger.Logger().Warn("not set SessionMode, but set enabledsession true, now will use default runtime session", LogTarget_HttpServer)
app.HttpServer.SetSessionConfig(session.NewDefaultRuntimeConfig())
@@ -380,6 +408,18 @@ func (app *DotWeb) DefaultHTTPErrorHandler(ctx Context, err error) {
}
}
+// DefaultNotFoundHandler default exception handler
+func (app *DotWeb) DefaultNotFoundHandler(ctx Context) {
+ ctx.Response().Header().Set(HeaderContentType, CharsetUTF8)
+ ctx.WriteStringC(http.StatusNotFound, http.StatusText(http.StatusNotFound))
+}
+
+// DefaultNotFoundHandler default exception handler
+func (app *DotWeb) DefaultMethodNotAllowedHandler(ctx Context) {
+ ctx.Response().Header().Set(HeaderContentType, CharsetUTF8)
+ ctx.WriteStringC(http.StatusMethodNotAllowed, http.StatusText(http.StatusMethodNotAllowed))
+}
+
// Close immediately stops the server.
// It internally calls `http.Server#Close()`.
func (app *DotWeb) Close() error {
diff --git a/example/main.go b/example/main.go
index 1c469a1..9ce5c0c 100644
--- a/example/main.go
+++ b/example/main.go
@@ -48,13 +48,14 @@ func main() {
//redis mode
//app.HttpServer.SetSessionConfig(session.NewDefaultRedisConfig("192.168.8.175:6379", ""))
+ app.HttpServer.SetEnabledDetailRequestData(true)
+
//设置路由
InitRoute(app.HttpServer)
//自定义404输出
- app.SetNotFoundHandle(func(w http.ResponseWriter, req *http.Request) {
- w.WriteHeader(http.StatusNotFound)
- w.Write([]byte("is't app's not found!"))
+ app.SetNotFoundHandle(func(ctx dotweb.Context) {
+ ctx.Response().Write(http.StatusNotFound, []byte("is't app's not found!"))
})
//设置HttpModule
diff --git a/feature.go b/feature.go
index 15103cb..92cdb00 100644
--- a/feature.go
+++ b/feature.go
@@ -56,14 +56,14 @@ func (f *xFeatureTools) SetGzip(httpCtx *HttpContext) {
func (f *xFeatureTools) InitFeatures(server *HttpServer, httpCtx *HttpContext) {
//gzip
- if server.ServerConfig.EnabledGzip {
+ if server.ServerConfig().EnabledGzip {
FeatureTools.SetGzip(httpCtx)
}
//session
//if exists client-sessionid, use it
//if not exists client-sessionid, new one
- if server.SessionConfig.EnabledSession {
+ if server.SessionConfig().EnabledSession {
FeatureTools.SetSession(httpCtx)
}
@@ -78,7 +78,7 @@ func (f *xFeatureTools) InitFeatures(server *HttpServer, httpCtx *HttpContext) {
}
func (f *xFeatureTools) ReleaseFeatures(server *HttpServer, httpCtx *HttpContext) {
- if server.ServerConfig.EnabledGzip {
+ if server.ServerConfig().EnabledGzip {
var w io.Writer
w = httpCtx.Response().Writer().(*gzipResponseWriter).Writer
w.(*gzip.Writer).Close()
diff --git a/router.go b/router.go
index a766738..5a3be23 100644
--- a/router.go
+++ b/router.go
@@ -117,24 +117,9 @@ type (
// RedirectTrailingSlash is independent of this option.
RedirectFixedPath bool
- // If enabled, the router checks if another method is allowed for the
- // current route, if the current request can not be routed.
- // If this is the case, the request is answered with 'Method Not Allowed'
- // and HTTP status code 405.
- // If no other Method is allowed, the request is delegated to the NotFound
- // handler.
- HandleMethodNotAllowed bool
-
// If enabled, the router automatically replies to OPTIONS requests.
// Custom OPTIONS handlers take priority over automatic replies.
HandleOPTIONS bool
-
- // Configurable http.Handler which is called when a request
- // cannot be routed and HandleMethodNotAllowed is true.
- // If it is not set, http.Error with http.StatusMethodNotAllowed is used.
- // The "Allow" header with allowed request methods is set before the handler
- // is called.
- MethodNotAllowed http.Handler
}
// Handle is a function that can be registered to a route to handle HTTP
@@ -169,13 +154,12 @@ func (ps Params) ByName(name string) string {
// Path auto-correction, including trailing slashes, is enabled by default.
func NewRouter(server *HttpServer) *router {
return &router{
- RedirectTrailingSlash: true,
- RedirectFixedPath: true,
- HandleMethodNotAllowed: true,
- HandleOPTIONS: true,
- server: server,
- handlerMap: make(map[string]HttpHandle),
- handlerMutex: new(sync.RWMutex),
+ RedirectTrailingSlash: true,
+ RedirectFixedPath: true,
+ HandleOPTIONS: true,
+ server: server,
+ handlerMap: make(map[string]HttpHandle),
+ handlerMutex: new(sync.RWMutex),
}
}
@@ -202,9 +186,6 @@ func (r *router) MatchPath(ctx Context, routePath string) bool {
// ServeHTTP makes the router implement the http.Handler interface.
func (r *router) ServeHTTP(ctx *HttpContext) {
- //增加状态计数
- core.GlobalState.AddRequestCount(ctx.Request().Path(), 1)
-
req := ctx.Request().Request
w := ctx.Response().Writer()
path := req.URL.Path
@@ -258,28 +239,17 @@ func (r *router) ServeHTTP(ctx *HttpContext) {
}
} else {
// Handle 405
- if r.HandleMethodNotAllowed {
- if allow := r.allowed(path, req.Method); len(allow) > 0 {
- w.Header().Set("Allow", allow)
- if r.MethodNotAllowed != nil {
- r.MethodNotAllowed.ServeHTTP(w, req)
- } else {
- http.Error(w,
- http.StatusText(http.StatusMethodNotAllowed),
- http.StatusMethodNotAllowed,
- )
- }
- return
- }
+ if allow := r.allowed(path, req.Method); len(allow) > 0 {
+ w.Header().Set("Allow", allow)
+ ctx.Response().SetStatusCode(http.StatusMethodNotAllowed)
+ r.server.DotApp.MethodNotAllowedHandler(ctx)
+ return
}
}
// Handle 404
- if r.server.DotApp.NotFoundHandler != nil {
- r.server.DotApp.NotFoundHandler(w, req)
- } else {
- http.NotFound(w, req)
- }
+ ctx.Response().SetStatusCode(http.StatusNotFound)
+ r.server.DotApp.NotFoundHandler(ctx)
}
//wrap HttpHandle to Handle
@@ -359,8 +329,6 @@ func (r *router) wrapRouterHandle(handler HttpHandle, isHijack bool) RouterHandl
//wrap fileHandler to httprouter.Handle
func (r *router) wrapFileHandle(fileHandler http.Handler) RouterHandle {
return func(httpCtx *HttpContext) {
- //增加状态计数
- core.GlobalState.AddRequestCount(httpCtx.Request().Path(), 1)
startTime := time.Now()
httpCtx.Request().URL.Path = httpCtx.RouterParams().ByName("filepath")
fileHandler.ServeHTTP(httpCtx.Response().Writer(), httpCtx.Request().Request)
@@ -454,7 +422,7 @@ func (r *router) RegisterRoute(routeMethod string, path string, handle HttpHandl
//if set auto-head, add head router
//only enabled in hijack\GET\POST\DELETE\PUT\HEAD\PATCH\OPTIONS
- if r.server.ServerConfig.EnabledAutoHEAD {
+ if r.server.ServerConfig().EnabledAutoHEAD {
if routeMethod == RouteMethod_HiJack {
r.add(RouteMethod_HEAD, path, r.wrapRouterHandle(handle, true))
} else if routeMethod != RouteMethod_Any {
@@ -473,7 +441,7 @@ func (r *router) ServerFile(path string, fileroot string) RouterNode {
}
var root http.FileSystem
root = http.Dir(fileroot)
- if !r.server.ServerConfig.EnabledListDir {
+ if !r.server.ServerConfig().EnabledListDir {
root = &core.HideReaddirFS{root}
}
fileServer := http.FileServer(root)
@@ -599,9 +567,6 @@ func (r *router) wrapWebSocketHandle(handler HttpHandle) websocket.Handler {
}()
handler(httpCtx)
-
- //增加状态计数
- core.GlobalState.AddRequestCount(httpCtx.Request().Path(), 1)
}
}
diff --git a/server.go b/server.go
index f890ff6..658a0aa 100644
--- a/server.go
+++ b/server.go
@@ -31,8 +31,6 @@ type (
sessionManager *session.SessionManager
lock_session *sync.RWMutex
pool *pool
- ServerConfig *config.ServerNode
- SessionConfig *config.SessionNode
binder Binder
render Renderer
offline bool
@@ -66,12 +64,10 @@ func NewHttpServer() *HttpServer {
},
},
},
- Modules: make([]*HttpModule, 0),
- ServerConfig: config.NewServerNode(),
- SessionConfig: config.NewSessionNode(),
- lock_session: new(sync.RWMutex),
- binder: newBinder(),
- Features: &feature.Feature{},
+ Modules: make([]*HttpModule, 0),
+ lock_session: new(sync.RWMutex),
+ binder: newBinder(),
+ Features: &feature.Feature{},
}
//设置router
server.router = NewRouter(server)
@@ -79,6 +75,16 @@ func NewHttpServer() *HttpServer {
return server
}
+// ServerConfig a shortcut for App.Config.ServerConfig
+func (server *HttpServer) ServerConfig() *config.ServerNode {
+ return server.DotApp.Config.Server
+}
+
+// SessionConfig a shortcut for App.Config.SessionConfig
+func (server *HttpServer) SessionConfig() *config.SessionNode {
+ return server.DotApp.Config.Session
+}
+
// ListenAndServe listens on the TCP network address srv.Addr and then
// calls Serve to handle requests on incoming connections.
func (server *HttpServer) ListenAndServe(addr string) error {
@@ -121,6 +127,8 @@ func (server *HttpServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
//针对websocket与调试信息特殊处理
if checkIsWebSocketRequest(req) {
http.DefaultServeMux.ServeHTTP(w, req)
+ //增加状态计数
+ core.GlobalState.AddRequestCount(req.URL.Path, defaultHttpCode, 1)
} else {
//设置header信息
w.Header().Set(HeaderServer, DefaultServerName)
@@ -154,8 +162,8 @@ func (server *HttpServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
}
- //add view count with httpcode
- core.GlobalState.AddTTPCodeCount(httpCtx.Request().Path(), httpCtx.Response().HttpCode(), 1)
+ //增加状态计数
+ core.GlobalState.AddRequestCount(httpCtx.Request().Path(), httpCtx.Response().HttpCode(), 1)
//release response
response.release()
@@ -182,28 +190,28 @@ func (server *HttpServer) SetOffline(offline bool, offlineText string, offlineUr
// IndexPage default index page name
func (server *HttpServer) IndexPage() string {
- if server.ServerConfig.IndexPage == "" {
+ if server.ServerConfig().IndexPage == "" {
return DefaultIndexPage
} else {
- return server.ServerConfig.IndexPage
+ return server.ServerConfig().IndexPage
}
}
// SetSessionConfig set session store config
func (server *HttpServer) SetSessionConfig(storeConfig *session.StoreConfig) {
//sync session config
- server.SessionConfig.Timeout = storeConfig.Maxlifetime
- server.SessionConfig.SessionMode = storeConfig.StoreName
- server.SessionConfig.ServerIP = storeConfig.ServerIP
+ server.SessionConfig().Timeout = storeConfig.Maxlifetime
+ server.SessionConfig().SessionMode = storeConfig.StoreName
+ server.SessionConfig().ServerIP = storeConfig.ServerIP
logger.Logger().Debug("DotWeb:HttpServer SetSessionConfig ["+jsonutil.GetJsonString(storeConfig)+"]", LogTarget_HttpServer)
}
// InitSessionManager init session manager
func (server *HttpServer) InitSessionManager() {
storeConfig := new(session.StoreConfig)
- storeConfig.Maxlifetime = server.SessionConfig.Timeout
- storeConfig.StoreName = server.SessionConfig.SessionMode
- storeConfig.ServerIP = server.SessionConfig.ServerIP
+ storeConfig.Maxlifetime = server.SessionConfig().Timeout
+ storeConfig.StoreName = server.SessionConfig().SessionMode
+ storeConfig.ServerIP = server.SessionConfig().ServerIP
if server.sessionManager == nil {
//设置Session
@@ -226,7 +234,7 @@ func (server *HttpServer) setDotApp(dotApp *DotWeb) {
// GetSessionManager get session manager in current httpserver
func (server *HttpServer) GetSessionManager() *session.SessionManager {
- if !server.SessionConfig.EnabledSession {
+ if !server.SessionConfig().EnabledSession {
return nil
}
return server.sessionManager
@@ -320,32 +328,32 @@ func (server *HttpServer) SetRenderer(r Renderer) {
// SetEnabledAutoHEAD set EnabledAutoHEAD true or false
func (server *HttpServer) SetEnabledAutoHEAD(autoHEAD bool) {
- server.ServerConfig.EnabledAutoHEAD = autoHEAD
+ server.ServerConfig().EnabledAutoHEAD = autoHEAD
logger.Logger().Debug("DotWeb:HttpServer SetEnabledAutoHEAD ["+strconv.FormatBool(autoHEAD)+"]", LogTarget_HttpServer)
}
// SetEnabledListDir 设置是否允许目录浏览,默认为false
func (server *HttpServer) SetEnabledListDir(isEnabled bool) {
- server.ServerConfig.EnabledListDir = isEnabled
+ server.ServerConfig().EnabledListDir = isEnabled
logger.Logger().Debug("DotWeb:HttpServer SetEnabledListDir ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
}
// SetEnabledSession 设置是否启用Session,默认为false
func (server *HttpServer) SetEnabledSession(isEnabled bool) {
- server.SessionConfig.EnabledSession = isEnabled
+ server.SessionConfig().EnabledSession = isEnabled
logger.Logger().Debug("DotWeb:HttpServer SetEnabledSession ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
}
// SetEnabledGzip 设置是否启用gzip,默认为false
func (server *HttpServer) SetEnabledGzip(isEnabled bool) {
- server.ServerConfig.EnabledGzip = isEnabled
+ server.ServerConfig().EnabledGzip = isEnabled
logger.Logger().Debug("DotWeb:HttpServer SetEnabledGzip ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
}
// SetEnabledIgnoreFavicon set IgnoreFavicon Enabled
// default is false
func (server *HttpServer) SetEnabledIgnoreFavicon(isEnabled bool) {
- server.ServerConfig.EnabledIgnoreFavicon = isEnabled
+ server.ServerConfig().EnabledIgnoreFavicon = isEnabled
logger.Logger().Debug("DotWeb:HttpServer SetEnabledIgnoreFavicon ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
server.RegisterModule(getIgnoreFaviconModule())
}
@@ -354,12 +362,18 @@ func (server *HttpServer) SetEnabledIgnoreFavicon(isEnabled bool) {
// default is false
// if it's true, must input certificate\private key fileName
func (server *HttpServer) SetEnabledTLS(isEnabled bool, certFile, keyFile string) {
- server.ServerConfig.EnabledTLS = isEnabled
- server.ServerConfig.TLSCertFile = certFile
- server.ServerConfig.TLSKeyFile = keyFile
+ server.ServerConfig().EnabledTLS = isEnabled
+ server.ServerConfig().TLSCertFile = certFile
+ server.ServerConfig().TLSKeyFile = keyFile
logger.Logger().Debug("DotWeb:HttpServer SetEnabledTLS ["+strconv.FormatBool(isEnabled)+","+certFile+","+keyFile+"]", LogTarget_HttpServer)
}
+// EnabledDetailRequestData 设置是否启用详细请求数据统计,默认为false
+func (server *HttpServer) SetEnabledDetailRequestData(isEnabled bool) {
+ server.ServerConfig().EnabledDetailRequestData = isEnabled
+ logger.Logger().Debug("DotWeb:HttpServer SetEnabledDetailRequestData ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
+}
+
// RegisterModule 添加处理模块
func (server *HttpServer) RegisterModule(module *HttpModule) {
server.Modules = append(server.Modules, module)
diff --git a/version.MD b/version.MD
index d88095e..0dbf050 100644
--- a/version.MD
+++ b/version.MD
@@ -1,5 +1,18 @@
## dotweb版本记录:
+#### Version 1.3.2
+* 主要新增设置启用详细请求数据控制,新增MethodNotAllowedHandler自定义能力,完善数据统计逻辑
+* 新增设置启用详细请求数据控制:
+* 1) ServerStateInfo增加EnabledDetailRequestData,用于控制是否启用详细请求数据统计
+* 2) config.ServerConfig增加EnabledDetailRequestData设置,支持配置文件控制
+* 3) HttpServer增加SetEnabledDetailRequestData函数,用于代码设置是否启用详细请求数据统计
+* 4) fixed #63 状态数据,当url较多时,导致内存占用过大
+* 新增MethodNotAllowedHandler自定义能力
+* 1) dotweb增加DefaultMethodNotAllowedHandler、SetMethodNotAllowedHandle函数
+* 完善数据统计逻辑
+* 1) 404请求不计入详细请求数据统计
+* 2017-10-13 12:00
+
#### Version 1.3.1
* 增加HttpServer.ServerFile,以支持server快捷设置静态文件目录
* 2017-10-11 22:00