From 975da97b4a39db53faf7a0d92827b79982b4b9a7 Mon Sep 17 00:00:00 2001 From: John Date: Tue, 5 Mar 2019 17:06:37 +0800 Subject: [PATCH] fix issue in empty check for nil attribute of struct in package 'empty';add set-cookie support for 302 status in ghttp.Server --- g/internal/empty/empty.go | 5 +++- g/net/ghttp/ghttp_response.go | 14 +++++++++-- g/net/ghttp/ghttp_response_writer.go | 13 ++++++---- g/net/ghttp/ghttp_server.go | 2 +- g/net/ghttp/ghttp_server_handler.go | 11 ++++----- geg/net/ghttp/server/session/session.go | 33 +++++++++++++++++++++++++ geg/other/test.go | 26 +++++++++++++------ 7 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 geg/net/ghttp/server/session/session.go diff --git a/g/internal/empty/empty.go b/g/internal/empty/empty.go index 44fcae22b..60d4d3406 100644 --- a/g/internal/empty/empty.go +++ b/g/internal/empty/empty.go @@ -36,7 +36,10 @@ func IsEmpty(value interface{}) bool { case []byte: return len(value) == 0 default: // 最后通过反射来判断 - rv := reflect.ValueOf(value) + rv := reflect.ValueOf(value) + if rv.IsNil() { + return true + } kind := rv.Kind() switch kind { case reflect.Map: fallthrough diff --git a/g/net/ghttp/ghttp_response.go b/g/net/ghttp/ghttp_response.go index f752971a2..705ee2856 100644 --- a/g/net/ghttp/ghttp_response.go +++ b/g/net/ghttp/ghttp_response.go @@ -187,7 +187,8 @@ func (r *Response) ServeFileDownload(path string, name...string) { r.Server.serveFile(r.request, path) } -// 返回location标识,引导客户端跳转 +// 返回location标识,引导客户端跳转。 +// 注意这里要先把设置的cookie输出,否则会被忽略。 func (r *Response) RedirectTo(location string) { r.Header().Set("Location", location) r.WriteHeader(http.StatusFound) @@ -220,10 +221,19 @@ func (r *Response) ClearBuffer() { r.buffer.Reset() } -// 输出缓冲区数据到客户端 +// Deprecated. +// +// 输出缓冲区数据到客户端. func (r *Response) OutputBuffer() { r.Header().Set("Server", r.Server.config.ServerAgent) //r.handleGzip() r.Writer.OutputBuffer() } +// 输出缓冲区数据到客户端. +func (r *Response) Output() { + r.Header().Set("Server", r.Server.config.ServerAgent) + //r.handleGzip() + r.Writer.OutputBuffer() +} + diff --git a/g/net/ghttp/ghttp_response_writer.go b/g/net/ghttp/ghttp_response_writer.go index e803f170e..0b0afba45 100644 --- a/g/net/ghttp/ghttp_response_writer.go +++ b/g/net/ghttp/ghttp_response_writer.go @@ -25,16 +25,19 @@ func (w *ResponseWriter) Write(data []byte) (int, error) { return len(data), nil } -// 覆盖父级的WriteHeader方法 -func (w *ResponseWriter) WriteHeader(code int) { - w.Status = code - w.ResponseWriter.WriteHeader(code) +// 覆盖父级的WriteHeader方法, 这里只会记录Status做缓冲处理, 并不会立即输出到HEADER。 +func (w *ResponseWriter) WriteHeader(status int) { + w.Status = status } -// 输出buffer数据到客户端 +// 输出buffer数据到客户端. func (w *ResponseWriter) OutputBuffer() { if w.buffer.Len() > 0 { w.ResponseWriter.Write(w.buffer.Bytes()) w.buffer.Reset() } + if w.Status != 0 { + w.ResponseWriter.WriteHeader(w.Status) + } } + diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index c223ded74..d59fa4a7d 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -147,7 +147,7 @@ var ( // 用于服务进程初始化,只能初始化一次,采用“懒初始化”(在server运行时才初始化) serverProcessInited = gtype.NewBool() - // 是否开启WebServer平滑重启特性, 会开启额外的本地端口监听,用于进程管理通信 + // 是否开启WebServer平滑重启特性, 会开启额外的本地端口监听,用于进程管理通信(默认开启) gracefulEnabled = true ) diff --git a/g/net/ghttp/ghttp_server_handler.go b/g/net/ghttp/ghttp_server_handler.go index 2dca11564..f837b207c 100644 --- a/g/net/ghttp/ghttp_server_handler.go +++ b/g/net/ghttp/ghttp_server_handler.go @@ -24,7 +24,7 @@ func (s *Server)defaultHttpHandle(w http.ResponseWriter, r *http.Request) { s.handleRequest(w, r) } -// 执行处理HTTP请求 +// 执行处理HTTP请求, // 首先,查找是否有对应域名的处理接口配置; // 其次,如果没有对应的自定义处理接口配置,那么走默认的域名处理接口配置; // 最后,如果以上都没有找到处理接口,那么进行文件处理; @@ -55,12 +55,11 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { // 输出Cookie request.Cookie.Output() // 输出缓冲区 - request.Response.OutputBuffer() + request.Response.Output() // 事件 - AfterOutput if !request.IsExited() { s.callHookHandler(HOOK_AFTER_OUTPUT, request) } - // 事件 - BeforeClose s.callHookHandler(HOOK_BEFORE_CLOSE, request) // access log @@ -92,7 +91,7 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { // 动态服务检索 handler := (*handlerItem)(nil) - if !request.IsFileRequest() || isStaticDir { + if !request.isFileRequest || isStaticDir { if parsedItem := s.getServeHandlerWithCache(request); parsedItem != nil { handler = parsedItem.handler for k, v := range parsedItem.values { @@ -112,9 +111,9 @@ func (s *Server)handleRequest(w http.ResponseWriter, r *http.Request) { // 执行静态文件服务/回调控制器/执行对象/方法 if !request.IsExited() { - // 需要再次判断文件是否真实存在,因为文件检索可能使用了缓存,从健壮性考虑这里需要二次判断 + // 需要再次判断文件是否真实存在, + // 因为文件检索可能使用了缓存,从健壮性考虑这里需要二次判断 if request.isFileRequest /* && gfile.Exists(staticFile) */{ - // 静态文件 s.serveFile(request, staticFile) } else { if handler != nil { diff --git a/geg/net/ghttp/server/session/session.go b/geg/net/ghttp/server/session/session.go new file mode 100644 index 000000000..e3f5fa9bd --- /dev/null +++ b/geg/net/ghttp/server/session/session.go @@ -0,0 +1,33 @@ +package main + +import ( + "github.com/gogf/gf/g" + "github.com/gogf/gf/g/frame/gmvc" +) + +type Controller struct { + gmvc.Controller +} + +func (c *Controller) Login() { + c.Session.Id() + c.Response.Write("这个页面用户填写信息执行登录") +} + +func (c *Controller) DoLogin() { + c.Session.Set("key", "value") + //c.Response.Header().Set("Set-Cookie", "myid=1B27UGQGCIBP0P70; Path=/; Domain=127.0.0.1; Expires=Wed, 04 Mar 2020 07:12:05 GMT") + + c.Response.RedirectTo("/main") +} + +func (c *Controller) Main() { + c.Response.WriteJson(c.Session.Data()) +} + +func main() { + s := g.Server() + s.BindController("/", new(Controller)) + s.SetPort(8199) + s.Run() +} diff --git a/geg/other/test.go b/geg/other/test.go index 21dff1c59..c0c204684 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,13 +1,23 @@ package main -import "fmt" +import ( + "fmt" + "github.com/gogf/gf/g/util/gconv" +) + +type User struct { + Id int +} + +type RPCResponse struct { + ID interface{} `json:"id,omitempty"` + JsonRPC string `json:"jsonrpc"` + Error *User `json:"error,omitempty"` + Result interface{} `json:"result,omitempty"` +} func main() { - for i := 0; i < 10; i++ { - switch 1 { - default: - //continue - } - fmt.Println(i) - } + var rpc RPCResponse + fmt.Println(rpc.Error) + fmt.Println(gconv.Map(rpc)) } \ No newline at end of file