Skip to content

Commit c0bfdaf

Browse files
author
pzrr@qq.com
committed
#### Version 1.2
* 国庆特别版 - 2017年的国庆,恰逢中秋双节,祝愿国家繁荣昌盛,祝愿代码艺术家们双节快乐! * 主要新增HttpModule模块、新增ServerConfig:EnabledIgnoreFavicon、完善HttpContext、完善debug日志输出 * 【新增】HttpModule模块,提供路由之前全局级别的自定义代码能力 * 1、新增module文件,将原dotweb文件中HttpMoule定义转移至module文件,新增Name属性 * 2、新增getIgnoreFaviconModule函数用于创建基础Module用于EnabledIgnoreFavicon特性 * 3、HttpServer新增RegisterModule函数,用于注册自定义HttpModule * 4、增加代码示例-根据参数动态变更访问路由 - package: example/httpmodule * 【新增】忽视favicon文件请求能力 * 1、通过ServerConfig:EnabledIgnoreFavicon设置,默认不启用 * 2、当启用该选项时,请求/facicon.ico文件时,将默认反馈空 * 3、配置文件server节点增加enabledignorefavicon设置项 * 【完善】HttpContext,使相关接口更清晰 * 1、新增WriteHtml、WriteHtmlC函数,默认设置Context-Type:text/html; charset=utf-8 * 3、注意,若在同一个请求期间,多次调用WriteHtml与WriteString,以最后一次调用的Context-Type为准 * 【完善】debug日志输出,使dotweb启动过程更清晰 * 1、新增Group创建日志 * 2、新增ServerConfig设置日志 * 3、新增设置Session参数日志 * 4、新增Session初始化日志 * 5、新增RegisterModule日志 * 2017-10-03 14:00
1 parent fc8cf4c commit c0bfdaf

9 files changed

Lines changed: 121 additions & 95 deletions

File tree

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ func StartServer() error {
3636
## 3. Features
3737
* 支持静态路由、参数路由、组路由
3838
* 路由支持文件/目录服务,支持设置是否允许目录浏览
39+
* HttpModule支持,支持路由之前全局级别的自定义代码能力
3940
* 中间件支持,支持App、Group、Router级别的设置 - https://github.com/devfeel/middleware
4041
* Feature支持,可绑定HttpServer全局启用
4142
* 支持STRING/JSON/JSONP/HTML格式输出

‎config/configs.go‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ type (
4141
}
4242

4343
ServerNode struct {
44-
EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启
45-
EnabledGzip bool `xml:"enabledgzip,attr"` //是否启用gzip
46-
EnabledAutoHEAD bool `xml:"enabledautohead,attr"` //设置是否自动启用Head路由,若设置该项,则会为除Websocket\HEAD外所有路由方式默认添加HEAD路由,默认不开启
47-
EnabledAutoCORS bool `xml:"enabledautocors,attr"` //设置是否自动跨域支持,若设置,默认“GET, POST, PUT, DELETE, OPTIONS”全部请求均支持跨域
48-
Port int `xml:"port,attr"` //端口
49-
IndexPage string `xml:"indexpage,attr"` //默认index页面
44+
EnabledListDir bool `xml:"enabledlistdir,attr"` //设置是否启用目录浏览,仅对Router.ServerFile有效,若设置该项,则可以浏览目录文件,默认不开启
45+
EnabledGzip bool `xml:"enabledgzip,attr"` //是否启用gzip
46+
EnabledAutoHEAD bool `xml:"enabledautohead,attr"` //设置是否自动启用Head路由,若设置该项,则会为除Websocket\HEAD外所有路由方式默认添加HEAD路由,默认不开启
47+
EnabledAutoCORS bool `xml:"enabledautocors,attr"` //设置是否自动跨域支持,若设置,默认“GET, POST, PUT, DELETE, OPTIONS”全部请求均支持跨域
48+
EnabledIgnoreFavicon bool `xml:"enabledignorefavicon,attr"` //设置是否忽略favicon.ico请求,若设置,网站将把所有favicon.ico请求直接空返回
49+
Port int `xml:"port,attr"` //端口
50+
IndexPage string `xml:"indexpage,attr"` //默认index页面
5051
}
5152

5253
SessionNode struct {

‎context.go‎

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ type (
6666
Write(code int, content []byte) (int, error)
6767
WriteString(contents ...interface{}) (int, error)
6868
WriteStringC(code int, contents ...interface{}) (int, error)
69+
WriteHtml(contents ...interface{}) (int, error)
70+
WriteHtmlC(code int, contents ...interface{}) (int, error)
6971
WriteBlob(contentType string, b []byte) (int, error)
7072
WriteBlobC(code int, contentType string, b []byte) (int, error)
7173
WriteJson(i interface{}) (int, error)
@@ -437,19 +439,26 @@ func (ctx *HttpContext) Write(code int, content []byte) (int, error) {
437439
}
438440
}
439441

440-
// WriteString write string content to response
442+
// WriteString write (200, string, text/plain) to response
441443
func (ctx *HttpContext) WriteString(contents ...interface{}) (int, error) {
442444
return ctx.WriteStringC(defaultHttpCode, contents...)
443445
}
444446

445-
// WriteStringC write (httpCode, string) to response
447+
// WriteStringC write (httpCode, string, text/plain) to response
446448
func (ctx *HttpContext) WriteStringC(code int, contents ...interface{}) (int, error) {
447449
content := fmt.Sprint(contents...)
448-
if ctx.IsHijack() {
449-
return ctx.hijackConn.WriteString(content)
450-
} else {
451-
return ctx.response.Write(code, []byte(content))
452-
}
450+
return ctx.WriteBlobC(code, "", []byte(content))
451+
}
452+
453+
// WriteString write (200, string, text/html) to response
454+
func (ctx *HttpContext) WriteHtml(contents ...interface{}) (int, error) {
455+
return ctx.WriteHtmlC(defaultHttpCode, contents...)
456+
}
457+
458+
// WriteHtmlC write (httpCode, string, text/html) to response
459+
func (ctx *HttpContext) WriteHtmlC(code int, contents ...interface{}) (int, error) {
460+
content := fmt.Sprint(contents...)
461+
return ctx.WriteBlobC(code, MIMETextHTMLCharsetUTF8, []byte(content))
453462
}
454463

455464
// WriteBlob write []byte content to response

‎dotweb.go‎

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ type (
2828
cache cache.Cache
2929
OfflineServer servers.Server
3030
Config *config.Config
31-
Modules []*HttpModule
3231
Middlewares []Middleware
3332
ExceptionHandler ExceptionHandle
3433
NotFoundHandler NotFoundHandle
@@ -58,7 +57,6 @@ func New() *DotWeb {
5857
app := &DotWeb{
5958
HttpServer: NewHttpServer(),
6059
OfflineServer: servers.NewOfflineServer(),
61-
Modules: make([]*HttpModule, 0),
6260
Middlewares: make([]Middleware, 0),
6361
AppContext: core.NewItemContext(),
6462
Config: config.NewConfig(),
@@ -141,12 +139,6 @@ func (app *DotWeb) UseRequestLog() {
141139
app.Use(&RequestLogMiddleware{})
142140
}
143141

144-
// Deprecated: Use the Middleware instead
145-
// RegisterModule 添加处理模块
146-
func (app *DotWeb) RegisterModule(module *HttpModule) {
147-
app.Modules = append(app.Modules, module)
148-
}
149-
150142
// SetExceptionHandle set custom error handler
151143
func (app *DotWeb) SetExceptionHandle(handler ExceptionHandle) {
152144
app.ExceptionHandler = handler

‎example/httpmodule/main.go‎

Lines changed: 35 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
package main
22

33
import (
4-
"context"
5-
"errors"
64
"fmt"
75
"github.com/devfeel/dotweb"
86
"github.com/devfeel/dotweb/framework/file"
97
"github.com/devfeel/dotweb/session"
108
"strconv"
11-
"time"
129
)
1310

1411
func main() {
@@ -21,9 +18,13 @@ func main() {
2118
//设置gzip开关
2219
//app.HttpServer.SetEnabledGzip(true)
2320

21+
app.SetDevelopmentMode()
22+
2423
//设置Session开关
2524
app.HttpServer.SetEnabledSession(true)
2625

26+
app.HttpServer.SetEnabledIgnoreFavicon(true)
27+
2728
//设置Session配置
2829
//runtime mode
2930
app.HttpServer.SetSessionConfig(session.NewDefaultRuntimeConfig())
@@ -34,7 +35,7 @@ func main() {
3435
InitRoute(app.HttpServer)
3536

3637
//设置HttpModule
37-
//InitModule(app)
38+
InitModule(app.HttpServer)
3839

3940
//启动 监控服务
4041
//app.SetPProfConfig(true, 8081)
@@ -52,71 +53,55 @@ func main() {
5253

5354
func Index(ctx dotweb.Context) error {
5455
ctx.Items().Set("count", 2)
55-
ctx.WriteString("index => " + ctx.Items().GetString("count"))
56+
ctx.WriteString(ctx.Request().Path() + ":Items.Count=> " + ctx.Items().GetString("count"))
5657
_, err := ctx.WriteString("\r\n")
5758
return err
5859
}
5960

60-
func CtxTimeOut(ctx dotweb.Context) error {
61-
ctx.SetTimeoutContext(time.Second * 3)
62-
runCtx := context.WithValue(ctx.Context(), "test", 1)
63-
err := sleepCtx(runCtx)
64-
ctx.WriteString(time.Now(), err)
61+
func WHtml(ctx dotweb.Context) error {
62+
ctx.WriteHtml("this is html response!")
6563
return nil
6664
}
6765

68-
func sleepCtx(runCtx context.Context) error {
69-
fmt.Println(runCtx.Value("RequestID"))
70-
fmt.Println(runCtx.Value("test"))
71-
c := make(chan error, 1)
72-
go func() {
73-
time.Sleep(time.Second * 5)
74-
fmt.Println(time.Now(), "sleep time end")
75-
c <- errors.New("test")
76-
}()
77-
select {
78-
case <-runCtx.Done():
79-
return runCtx.Err()
80-
case err := <-c:
81-
return err
82-
}
83-
}
84-
85-
func sleep(runCtx context.Context) error {
86-
fmt.Println(runCtx.Value("RequestID"))
87-
time.Sleep(time.Second * 5)
88-
fmt.Println(time.Now(), "sleep time end")
89-
return errors.New("test")
90-
}
91-
92-
93-
9466
func InitRoute(server *dotweb.HttpServer) {
9567
server.GET("/", Index)
96-
server.GET("/user", Index) //need login
97-
server.GET("/login", Index)
98-
server.GET("/reg", Index)
99-
server.GET("/ctx", CtxTimeOut)
68+
server.GET("/m", Index)
69+
server.GET("/h", WHtml)
10070
}
10171

102-
func InitModule(dotserver *dotweb.DotWeb) {
72+
func InitModule(dotserver *dotweb.HttpServer) {
10373
dotserver.RegisterModule(&dotweb.HttpModule{
74+
Name: "test change route",
10475
OnBeginRequest: func(ctx dotweb.Context) {
105-
if ctx.HttpServer().Router().MatchPath(ctx, "/user") {
106-
//TODO:need login
76+
if ctx.IsEnd() {
77+
return
78+
}
79+
if ctx.Request().Path() == "/" && ctx.QueryString("change") == "1" {
80+
//change route
81+
ctx.WriteString("变更访问路由测试")
82+
ctx.WriteString("\r\n")
83+
ctx.Request().URL.Path = "/m"
84+
}
85+
86+
if ctx.Request().Path() == "/" {
87+
ctx.Items().Set("count", 1)
88+
ctx.WriteString("OnBeginRequest:Items.Count => ", ctx.Items().GetString("count"))
89+
ctx.WriteString("\r\n")
10790
}
108-
ctx.Items().Set("count", 1)
109-
ctx.WriteString("OnBeginRequest => ", ctx.Items().GetString("count"))
110-
ctx.WriteString("\r\n")
11191
if ctx.QueryString("skip") == "1" {
11292
ctx.End()
11393
}
11494
},
11595
OnEndRequest: func(ctx dotweb.Context) {
116-
if ctx.Items().Exists("count") {
117-
ctx.WriteString("OnEndRequest => ", ctx.Items().GetString("count"))
118-
} else {
119-
ctx.WriteString("OnEndRequest => ", ctx.Items().Len())
96+
if ctx.IsEnd() {
97+
return
98+
}
99+
if ctx.Request().Path() == "/" {
100+
if ctx.Items().Exists("count") {
101+
ctx.WriteString("OnEndRequest:Items.Count => ", ctx.Items().GetString("count"))
102+
} else {
103+
ctx.WriteString("OnEndRequest:Items.Len => ", ctx.Items().Len())
104+
}
120105
}
121106
},
122107
})

‎group.go‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dotweb
22

3+
import "github.com/devfeel/dotweb/logger"
4+
35
type (
46
Group interface {
57
Use(m ...Middleware) Group
@@ -22,6 +24,7 @@ type (
2224

2325
func NewGroup(prefix string, server *HttpServer) Group {
2426
g := &xGroup{prefix: prefix, server: server}
27+
logger.Logger().Debug("Dotweb:Group NewGroup ["+prefix+"]", LogTarget_HttpServer)
2528
return g
2629
}
2730

‎router.go‎

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -337,13 +337,6 @@ func (r *router) wrapRouterHandle(handler HttpHandle, isHijack bool) RouterHandl
337337
}
338338
}()
339339

340-
//处理前置Module集合
341-
for _, module := range r.server.DotApp.Modules {
342-
if module.OnBeginRequest != nil {
343-
module.OnBeginRequest(httpCtx)
344-
}
345-
}
346-
347340
//处理用户handle
348341
var ctxErr error
349342
if len(r.server.DotApp.Middlewares) > 0 {
@@ -360,12 +353,6 @@ func (r *router) wrapRouterHandle(handler HttpHandle, isHijack bool) RouterHandl
360353
}
361354
}
362355

363-
//处理后置Module集合
364-
for _, module := range r.server.DotApp.Modules {
365-
if module.OnEndRequest != nil {
366-
module.OnEndRequest(httpCtx)
367-
}
368-
}
369356
}
370357
}
371358

‎server.go‎

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/devfeel/dotweb/config"
1111
"github.com/devfeel/dotweb/feature"
12+
"github.com/devfeel/dotweb/framework/json"
1213
"github.com/devfeel/dotweb/logger"
1314
"strconv"
1415
)
@@ -20,19 +21,11 @@ const (
2021
)
2122

2223
type (
23-
// Deprecated: Use the Middleware instead
24-
// HttpModule struct
25-
HttpModule struct {
26-
//响应请求时作为 HTTP 执行管线链中的第一个事件发生
27-
OnBeginRequest func(Context)
28-
//响应请求时作为 HTTP 执行管线链中的最后一个事件发生。
29-
OnEndRequest func(Context)
30-
}
31-
3224
//HttpServer定义
3325
HttpServer struct {
3426
stdServer *http.Server
3527
router Router
28+
Modules []*HttpModule
3629
DotApp *DotWeb
3730
sessionManager *session.SessionManager
3831
lock_session *sync.RWMutex
@@ -72,6 +65,7 @@ func NewHttpServer() *HttpServer {
7265
},
7366
},
7467
},
68+
Modules: make([]*HttpModule, 0),
7569
ServerConfig: config.NewServerNode(),
7670
SessionConfig: config.NewSessionNode(),
7771
lock_session: new(sync.RWMutex),
@@ -111,8 +105,25 @@ func (server *HttpServer) ServeHTTP(w http.ResponseWriter, req *http.Request) {
111105
httpCtx := server.pool.context.Get().(*HttpContext)
112106
httpCtx.reset(response, request, server, nil, nil, nil)
113107

114-
server.Router().ServeHTTP(httpCtx)
115-
108+
//处理前置Module集合
109+
for _, module := range server.Modules {
110+
if module.OnBeginRequest != nil {
111+
module.OnBeginRequest(httpCtx)
112+
}
113+
}
114+
115+
if !httpCtx.IsEnd() {
116+
server.Router().ServeHTTP(httpCtx)
117+
}
118+
119+
//处理后置Module集合
120+
for _, module := range server.Modules {
121+
if module.OnEndRequest != nil {
122+
module.OnEndRequest(httpCtx)
123+
}
124+
}
125+
126+
//add view count with httpcode
116127
core.GlobalState.AddTTPCodeCount(httpCtx.Request().Path(), httpCtx.Response().HttpCode(), 1)
117128

118129
//release response
@@ -153,6 +164,7 @@ func (server *HttpServer) SetSessionConfig(storeConfig *session.StoreConfig) {
153164
server.SessionConfig.Timeout = storeConfig.Maxlifetime
154165
server.SessionConfig.SessionMode = storeConfig.StoreName
155166
server.SessionConfig.ServerIP = storeConfig.ServerIP
167+
logger.Logger().Debug("Dotweb:HttpServer SetSessionConfig ["+jsonutil.GetJsonString(storeConfig)+"]", LogTarget_HttpServer)
156168
}
157169

158170
// InitSessionManager init session manager
@@ -173,6 +185,7 @@ func (server *HttpServer) InitSessionManager() {
173185
}
174186
server.lock_session.Unlock()
175187
}
188+
logger.Logger().Debug("Dotweb:HttpServer InitSessionManager ["+jsonutil.GetJsonString(storeConfig)+"]", LogTarget_HttpServer)
176189
}
177190

178191
// setDotApp 关联当前HttpServer实例对应的DotServer实例
@@ -290,6 +303,18 @@ func (server *HttpServer) SetEnabledGzip(isEnabled bool) {
290303
logger.Logger().Debug("Dotweb:HttpServer SetEnabledGzip ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
291304
}
292305

306+
func (server *HttpServer) SetEnabledIgnoreFavicon(isEnabled bool) {
307+
server.ServerConfig.EnabledIgnoreFavicon = isEnabled
308+
logger.Logger().Debug("Dotweb:HttpServer SetEnabledIgnoreFavicon ["+strconv.FormatBool(isEnabled)+"]", LogTarget_HttpServer)
309+
server.RegisterModule(getIgnoreFaviconModule())
310+
}
311+
312+
// RegisterModule 添加处理模块
313+
func (server *HttpServer) RegisterModule(module *HttpModule) {
314+
server.Modules = append(server.Modules, module)
315+
logger.Logger().Debug("Dotweb:HttpServer RegisterModule ["+module.Name+"]", LogTarget_HttpServer)
316+
}
317+
293318
type LogJson struct {
294319
RequestUrl string
295320
HttpHeader string

0 commit comments

Comments
 (0)