diff --git a/g/net/ghttp/http_request.go b/g/net/ghttp/http_request.go index e46a5c9ca..fa7209fcf 100644 --- a/g/net/ghttp/http_request.go +++ b/g/net/ghttp/http_request.go @@ -12,6 +12,7 @@ import ( "gitee.com/johng/gf/g/util/gconv" "gitee.com/johng/gf/g/encoding/gjson" "gitee.com/johng/gf/g/container/gtype" + "gitee.com/johng/gf/g/util/gregx" ) // 请求对象 @@ -39,8 +40,7 @@ func newRequest(s *Server, r *http.Request, w http.ResponseWriter) *Request { Server : s, Request : *r, Response : &Response { - status : http.StatusOK, - ResponseWriter : w, + ResponseWriter : ResponseWriter{w, http.StatusOK, 0}, }, } // 会话处理 @@ -298,5 +298,12 @@ func (r *Request) IsExited() bool { return r.exit.Val() } - +// 获取请求的客户端Ip地址 +func (r *Request) GetClientIp() string { + array, _ := gregx.MatchString(`(.+):(\d+)`, r.RemoteAddr) + if len(array) > 1 { + return array[1] + } + return r.RemoteAddr +} diff --git a/g/net/ghttp/http_response.go b/g/net/ghttp/http_response.go index e071403ed..429c99b1d 100644 --- a/g/net/ghttp/http_response.go +++ b/g/net/ghttp/http_response.go @@ -17,11 +17,30 @@ import ( // 服务端请求返回对象 type Response struct { - http.ResponseWriter - bufmu sync.RWMutex // 缓冲区互斥锁 + ResponseWriter + mu sync.RWMutex // 缓冲区互斥锁 buffer []byte // 每个请求的返回数据缓冲区 request *Request // 关联的Request请求对象 - status int // 返回状态码 +} + +// 自定义的ResponseWriter,用于写入流的控制 +type ResponseWriter struct { + http.ResponseWriter + status int // http status + length int // response length +} + +// 覆盖父级的WriteHeader方法 +func (w *ResponseWriter) Write(buffer []byte) (int, error) { + n, e := w.ResponseWriter.Write(buffer) + w.length += n + return n, e +} + +// 覆盖父级的WriteHeader方法 +func (w *ResponseWriter) WriteHeader(code int) { + w.status = code + w.ResponseWriter.WriteHeader(code) } // 返回信息,任何变量自动转换为bytes @@ -29,11 +48,11 @@ func (r *Response) Write(content ... interface{}) { if len(content) == 0 { return } - r.bufmu.Lock() + r.mu.Lock() for _, v := range content { r.buffer = append(r.buffer, gconv.Bytes(v)...) } - r.bufmu.Unlock() + r.mu.Unlock() } // 返回信息,末尾增加换行标识符"\n" @@ -99,7 +118,6 @@ func (r *Response) SetAllowCrossDomainRequest(allowOrigin string, allowMethods s // 返回HTTP Code状态码 func (r *Response) WriteStatus(code int, content...string) { - r.status = code r.Header().Set("Content-Type", "text/plain; charset=utf-8") r.Header().Set("X-Content-Type-Options", "nosniff") if len(content) > 0 { @@ -118,31 +136,31 @@ func (r *Response) RedirectTo(location string) { // 获取当前缓冲区中的数据 func (r *Response) Buffer() []byte { - r.bufmu.RLock() - defer r.bufmu.RUnlock() + r.mu.RLock() + defer r.mu.RUnlock() return r.buffer } // 手动设置缓冲区内容 func (r *Response) SetBuffer(buffer []byte) { - r.bufmu.Lock() + r.mu.Lock() r.buffer = buffer - r.bufmu.Unlock() + r.mu.Unlock() } // 清空缓冲区内容 func (r *Response) ClearBuffer() { - r.bufmu.Lock() + r.mu.Lock() r.buffer = make([]byte, 0) - r.bufmu.Unlock() + r.mu.Unlock() } // 输出缓冲区数据到客户端 func (r *Response) OutputBuffer() { - r.bufmu.Lock() + r.mu.Lock() if len(r.buffer) > 0 { r.ResponseWriter.Write(r.buffer) r.buffer = make([]byte, 0) } - r.bufmu.Unlock() + r.mu.Unlock() } diff --git a/g/net/ghttp/http_server_cookie.go b/g/net/ghttp/http_server_cookie.go index 9d1d0db49..82f93c6d7 100644 --- a/g/net/ghttp/http_server_cookie.go +++ b/g/net/ghttp/http_server_cookie.go @@ -130,7 +130,7 @@ func (c *Cookie) Output() { continue } http.SetCookie( - c.response.ResponseWriter, + c.response.ResponseWriter.ResponseWriter, &http.Cookie { Name : k, Value : v.value, diff --git a/g/net/ghttp/http_server_handler.go b/g/net/ghttp/http_server_handler.go index 403d54114..0523f3795 100644 --- a/g/net/ghttp/http_server_handler.go +++ b/g/net/ghttp/http_server_handler.go @@ -136,7 +136,7 @@ func (s *Server)doServeFile(r *Request, path string) { } } else { // 读取文件内容返回, no buffer - http.ServeContent(r.Response.ResponseWriter, &r.Request, info.Name(), info.ModTime(), f) + http.ServeContent(r.Response.ResponseWriter.ResponseWriter, &r.Request, info.Name(), info.ModTime(), f) } f.Close() } diff --git a/g/net/ghttp/http_server_log.go b/g/net/ghttp/http_server_log.go index d3be385ff..57384c4ab 100644 --- a/g/net/ghttp/http_server_log.go +++ b/g/net/ghttp/http_server_log.go @@ -9,7 +9,6 @@ package ghttp import ( "fmt" - "strings" "gitee.com/johng/gf/g/util/gconv" ) @@ -23,12 +22,8 @@ func (s *Server) handleAccessLog(r *Request) { v(r) return } - status := gconv.String(r.Response.status) - if v := r.Response.Header().Get("Status Code"); v != "" { - status = v - } - content := fmt.Sprintf(`"%s %s %s %s" %s`, r.Method, r.Host, r.URL.String(), r.Proto, status) - content += fmt.Sprintf(`, %s, "%s", "%s"`, strings.Split(r.RemoteAddr, ":")[0], r.Referer(), r.UserAgent()) + content := fmt.Sprintf(`"%s %s %s %s" %s %s`, r.Method, r.Host, r.URL.String(), r.Proto, gconv.String(r.Response.status), gconv.String(r.Response.length)) + content += fmt.Sprintf(`, %s, "%s", "%s"`, r.GetClientIp(), r.Referer(), r.UserAgent()) s.logger.Println(content) } @@ -44,7 +39,7 @@ func (s *Server) handleErrorLog(error interface{}, r *Request) { } content := fmt.Sprintf(`"%s %s %s %s"`, r.Method, r.Host, r.URL.String(), r.Proto) - content += fmt.Sprintf(`, %s, "%s", "%s"`, strings.Split(r.RemoteAddr, ":")[0], r.Referer(), r.UserAgent()) + content += fmt.Sprintf(`, %s, "%s", "%s"`, r.GetClientIp(), r.Referer(), r.UserAgent()) content += fmt.Sprintf(`, %v`, error) s.logger.Error(content) } diff --git a/g/net/ghttp/http_server_pprof.go b/g/net/ghttp/http_server_pprof.go index 0ab008b1c..622fab9fb 100644 --- a/g/net/ghttp/http_server_pprof.go +++ b/g/net/ghttp/http_server_pprof.go @@ -46,26 +46,26 @@ func (p *utilpprof) Index(r *Request) { } for _, p := range profiles { if p.Name() == action { - p.WriteTo(r.Response.ResponseWriter, r.GetRequestInt("debug")) + p.WriteTo(r.Response.ResponseWriter.ResponseWriter, r.GetRequestInt("debug")) break } } } func (p *utilpprof) Cmdline(r *Request) { - netpprof.Cmdline(r.Response.ResponseWriter, &r.Request) + netpprof.Cmdline(r.Response.ResponseWriter.ResponseWriter, &r.Request) } func (p *utilpprof) Profile(r *Request) { - netpprof.Profile(r.Response.ResponseWriter, &r.Request) + netpprof.Profile(r.Response.ResponseWriter.ResponseWriter, &r.Request) } func (p *utilpprof) Symbol(r *Request) { - netpprof.Symbol(r.Response.ResponseWriter, &r.Request) + netpprof.Symbol(r.Response.ResponseWriter.ResponseWriter, &r.Request) } func (p *utilpprof) Trace(r *Request) { - netpprof.Trace(r.Response.ResponseWriter, &r.Request) + netpprof.Trace(r.Response.ResponseWriter.ResponseWriter, &r.Request) } // 开启pprof支持