From f5ca1ab1a980e4ef5ae30b32e761db0950f488de Mon Sep 17 00:00:00 2001 From: John Date: Tue, 4 Sep 2018 23:40:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=97=A5=E5=BF=97=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9=E5=A4=A7=E5=B0=8F=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=EF=BC=9B=E6=A8=A1=E6=9D=BF=E5=BC=95=E6=93=8E=E6=96=B0=E5=A2=9E?= =?UTF-8?q?Config=E5=86=85=E7=BD=AE=E5=8F=98=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/net/ghttp/ghttp_response.go | 22 +++++++++++++++++++--- g/net/ghttp/ghttp_response_view.go | 7 ++++--- g/net/ghttp/ghttp_server_handler.go | 1 + g/net/ghttp/ghttp_server_log.go | 7 +++---- 4 files changed, 27 insertions(+), 10 deletions(-) diff --git a/g/net/ghttp/ghttp_response.go b/g/net/ghttp/ghttp_response.go index ff4d9bb0b..7cbeab886 100644 --- a/g/net/ghttp/ghttp_response.go +++ b/g/net/ghttp/ghttp_response.go @@ -19,7 +19,8 @@ import ( // 注意该对象并没有实现http.ResponseWriter接口,而是依靠ghttp.ResponseWriter实现。 type Response struct { ResponseWriter - Server *Server + length int // 请求返回的内容长度(byte) + Server *Server // 所属Web Server Writer *ResponseWriter // ResponseWriter的别名 request *Request // 关联的Request请求对象 } @@ -43,18 +44,21 @@ func (r *Response) Write(content ... interface{}) { if len(content) == 0 { return } - r.mu.Lock() for _, v := range content { switch v.(type) { case []byte: // 如果是二进制数据,那么返回二进制数据 + r.mu.Lock() r.buffer = append(r.buffer, gconv.Bytes(v)...) + r.mu.Unlock() default: // 否则一律按照可显示的字符串进行转换 + r.mu.Lock() r.buffer = append(r.buffer, gconv.String(v)...) + r.mu.Unlock() } } - r.mu.Unlock() + r.length = len(r.buffer) } // 返回信息,支持自定义format格式 @@ -187,6 +191,7 @@ func (r *Response) BufferLength() int { // 手动设置缓冲区内容 func (r *Response) SetBuffer(buffer []byte) { + r.length = 0 r.mu.Lock() r.buffer = buffer r.mu.Unlock() @@ -205,3 +210,14 @@ func (r *Response) OutputBuffer() { //r.handleGzip() r.Writer.OutputBuffer() } + +// 获取输出到客户端的数据大小 +func (r *Response) ContentSize() int { + if r.length > 0 { + return r.length + } + if length := r.Header().Get("Content-Length"); length != "" { + return gconv.Int(length) + } + return r.BufferLength() +} diff --git a/g/net/ghttp/ghttp_response_view.go b/g/net/ghttp/ghttp_response_view.go index 2d9cef918..a7c1eb014 100644 --- a/g/net/ghttp/ghttp_response_view.go +++ b/g/net/ghttp/ghttp_response_view.go @@ -48,7 +48,7 @@ func (r *Response) ParseTpl(tpl string, params map[string]interface{}, funcmap.. if len(funcmap) > 0 { fmap = funcmap[0] } - return gins.View().Parse(tpl, r.buildInParams(params), r.buildInfuncs(fmap)) + return gins.View().Parse(tpl, r.buildInVars(params), r.buildInfuncs(fmap)) } // 解析并返回模板内容 @@ -57,11 +57,12 @@ func (r *Response) ParseTplContent(content string, params map[string]interface{} if len(funcmap) > 0 { fmap = funcmap[0] } - return gins.View().ParseContent(content, r.buildInParams(params), r.buildInfuncs(fmap)) + return gins.View().ParseContent(content, r.buildInVars(params), r.buildInfuncs(fmap)) } // 内置变量 -func (r *Response) buildInParams(params map[string]interface{}) map[string]interface{} { +func (r *Response) buildInVars(params map[string]interface{}) map[string]interface{} { + params["Config"] = gins.Config().GetMap("") params["Cookie"] = r.request.Cookie.Map() params["Session"] = r.request.Session.Data() return params diff --git a/g/net/ghttp/ghttp_server_handler.go b/g/net/ghttp/ghttp_server_handler.go index 424d5f16c..f3d36c2c3 100644 --- a/g/net/ghttp/ghttp_server_handler.go +++ b/g/net/ghttp/ghttp_server_handler.go @@ -165,6 +165,7 @@ func (s *Server)serveFile(r *Request, path string) { } } else { // 读取文件内容返回, no buffer + r.Response.length = int(info.Size()) http.ServeContent(r.Response.Writer, &r.Request, info.Name(), info.ModTime(), f) } } diff --git a/g/net/ghttp/ghttp_server_log.go b/g/net/ghttp/ghttp_server_log.go index cbc3e0287..5901fe80c 100644 --- a/g/net/ghttp/ghttp_server_log.go +++ b/g/net/ghttp/ghttp_server_log.go @@ -9,7 +9,6 @@ package ghttp import ( "fmt" - "gitee.com/johng/gf/g/util/gconv" "net/http" ) @@ -23,10 +22,10 @@ func (s *Server) handleAccessLog(r *Request) { v(r) return } - content := fmt.Sprintf(`"%s %s %s %s" %s %s`, + content := fmt.Sprintf(`"%s %s %s %s" %d %d`, r.Method, r.Host, r.URL.String(), r.Proto, - gconv.String(r.Response.Status), - gconv.String(r.Response.BufferLength()), + r.Response.Status, + r.Response.ContentSize(), ) content += fmt.Sprintf(` %.3f`, float64(r.LeaveTime - r.EnterTime)/1000) content += fmt.Sprintf(`, %s, "%s", "%s"`, r.GetClientIp(), r.Referer(), r.UserAgent())