improve status handling and add error logger for ghttp.Server; fix issue in defer error warpping for some packages

This commit is contained in:
John 2019-10-11 22:54:25 +08:00
parent 74d625ff97
commit 5092d8e6c5
14 changed files with 70 additions and 80 deletions

View File

@ -13,7 +13,6 @@ import (
"io"
"os"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/util/gconv"
)
@ -43,9 +42,7 @@ func EncryptFile(path string) (encrypt string, err error) {
if err != nil {
return "", err
}
defer func() {
err = gerror.Wrap(f.Close(), "file closing error")
}()
defer f.Close()
h := md5.New()
_, err = io.Copy(h, f)
if err != nil {

View File

@ -13,7 +13,6 @@ import (
"io"
"os"
"github.com/gogf/gf/errors/gerror"
"github.com/gogf/gf/util/gconv"
)
@ -30,9 +29,7 @@ func EncryptFile(path string) (encrypt string, err error) {
if err != nil {
return "", err
}
defer func() {
err = gerror.Wrap(f.Close(), "file closing error")
}()
defer f.Close()
h := sha1.New()
_, err = io.Copy(h, f)
if err != nil {

View File

@ -107,12 +107,12 @@ func (m *Middleware) Next() {
m.request.Response.WriteStatus(http.StatusInternalServerError, exception)
})
}
// Handle the http status code after all handler and middleware done.
// Check the http status code after all handler and middleware done.
if m.request.Response.Status == 0 {
if m.request.Middleware.served || m.request.Response.buffer.Len() > 0 {
m.request.Response.Status = http.StatusOK
m.request.Response.WriteHeader(http.StatusOK)
} else {
m.request.Response.WriteStatus(http.StatusNotFound)
m.request.Response.WriteHeader(http.StatusNotFound)
}
}
}

View File

@ -131,30 +131,11 @@ func (r *Response) WriteXml(content interface{}, rootTag ...string) error {
// WriteStatus writes HTTP <status> and <content> to the response.
func (r *Response) WriteStatus(status int, content ...interface{}) {
// Avoid error: http: multiple response.WriteHeader calls.
if r.Status == 0 {
r.WriteHeader(status)
}
if r.buffer.Len() == 0 {
// HTTP status handler.
if status != http.StatusOK {
if f := r.Request.Server.getStatusHandler(status, r.Request); f != nil {
// Call custom status code handler.
niceCallFunc(func() {
f(r.Request)
})
return
}
}
if r.Header().Get("Content-Type") == "" {
r.Header().Set("Content-Type", "text/plain; charset=utf-8")
//r.Header().Set("X-Content-Type-Options", "nosniff")
}
if len(content) > 0 {
r.Write(content...)
} else {
r.Write(http.StatusText(status))
}
r.WriteHeader(status)
if len(content) > 0 {
r.Write(content...)
} else {
r.Write(http.StatusText(status))
}
}

View File

@ -49,9 +49,14 @@ func (w *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
// OutputBuffer outputs the buffer to client.
func (w *ResponseWriter) OutputBuffer() {
if w.Status != 0 {
// Use "Content-Length" header check to avoid error: superfluous response.WriteHeader call
if w.Status != 0 && w.Header().Get("Content-Length") == "" {
w.writer.WriteHeader(w.Status)
}
// Default status text output.
if w.Status != http.StatusOK && w.buffer.Len() == 0 {
w.buffer.WriteString(http.StatusText(w.Status))
}
if w.buffer.Len() > 0 {
w.writer.Write(w.buffer.Bytes())
w.buffer.Reset()

View File

@ -0,0 +1,23 @@
// Copyright 2018 gf Author(https://github.com/gogf/gf). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package ghttp
import (
"bytes"
"github.com/gogf/gf/os/glog"
)
// errorLogger is the error logging logger for underlying net/http.Server.
type errorLogger struct {
logger *glog.Logger
}
// Write implements the io.Writer interface.
func (l *errorLogger) Write(p []byte) (n int, err error) {
l.logger.Skip(1).Error(string(bytes.TrimRight(p, "\r\n")))
return len(p), nil
}

View File

@ -11,6 +11,7 @@ import (
"crypto/tls"
"errors"
"fmt"
"log"
"net"
"net/http"
"os"
@ -53,6 +54,7 @@ func (s *Server) newHttpServer(itemFunc string) *http.Server {
WriteTimeout: s.config.WriteTimeout,
IdleTimeout: s.config.IdleTimeout,
MaxHeaderBytes: s.config.MaxHeaderBytes,
ErrorLog: log.New(&errorLogger{logger: s.logger}, "", 0),
}
server.SetKeepAlivesEnabled(s.config.KeepAlive)
return server

View File

@ -121,7 +121,7 @@ func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) {
if len(request.Response.Header()) == 0 &&
request.Response.Status == 0 &&
request.Response.BufferLength() == 0 {
request.Response.WriteStatus(http.StatusNotFound)
request.Response.WriteHeader(http.StatusNotFound)
}
}
}
@ -138,14 +138,27 @@ func (s *Server) handleRequest(w http.ResponseWriter, r *http.Request) {
s.callHookHandler(HOOK_BEFORE_OUTPUT, request)
}
// 返回状态码处理
// HTTP status checking.
if request.Response.Status == 0 {
if request.Middleware.served || request.Response.buffer.Len() > 0 {
request.Response.Status = http.StatusOK
request.Response.WriteHeader(http.StatusOK)
} else {
request.Response.WriteStatus(http.StatusNotFound)
request.Response.WriteHeader(http.StatusNotFound)
}
}
// HTTP status handler.
if request.Response.Status != http.StatusOK {
if f := s.getStatusHandler(request.Response.Status, request); f != nil {
// Call custom status handler.
niceCallFunc(func() {
f(request)
})
}
}
if request.Response.Header().Get("Content-Type") == "" {
request.Response.Header().Set("Content-Type", "text/plain; charset=utf-8")
//r.Header().Set("X-Content-Type-Options", "nosniff")
}
// 设置Session Id到Cookie中
if request.Session.IsDirty() && request.Session.Id() != request.GetSessionId() {

View File

@ -4,7 +4,8 @@
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
// 静态文件服务测试
// static service testing.
package ghttp_test
import (

View File

@ -13,8 +13,6 @@ import (
"io"
"net"
"time"
"github.com/gogf/gf/errors/gerror"
)
// TCP connection object.
@ -208,9 +206,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
return nil, err
}
defer func() {
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
defer c.SetRecvDeadline(time.Time{})
data, err = c.Recv(length, retry...)
return
}
@ -220,9 +216,7 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
return err
}
defer func() {
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
defer c.SetSendDeadline(time.Time{})
err = c.Send(data, retry...)
return
}

View File

@ -10,8 +10,6 @@ import (
"encoding/binary"
"fmt"
"time"
"github.com/gogf/gf/errors/gerror"
)
const (
@ -77,9 +75,7 @@ func (c *Conn) SendPkgWithTimeout(data []byte, timeout time.Duration, option ...
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
return err
}
defer func() {
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
defer c.SetSendDeadline(time.Time{})
err = c.SendPkg(data, option...)
return
}
@ -161,9 +157,7 @@ func (c *Conn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption) (d
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
return nil, err
}
defer func() {
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
defer c.SetRecvDeadline(time.Time{})
data, err = c.RecvPkg(option...)
return
}

View File

@ -11,7 +11,6 @@ import (
"github.com/gogf/gf/container/gmap"
"github.com/gogf/gf/container/gpool"
"github.com/gogf/gf/errors/gerror"
)
// 链接池链接对象
@ -120,9 +119,7 @@ func (c *PoolConn) RecvWithTimeout(length int, timeout time.Duration, retry ...R
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
return nil, err
}
defer func() {
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
defer c.SetRecvDeadline(time.Time{})
data, err = c.Recv(length, retry...)
return
}
@ -132,9 +129,7 @@ func (c *PoolConn) SendWithTimeout(data []byte, timeout time.Duration, retry ...
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
return err
}
defer func() {
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
defer c.SetSendDeadline(time.Time{})
err = c.Send(data, retry...)
return
}

View File

@ -8,8 +8,6 @@ package gtcp
import (
"time"
"github.com/gogf/gf/errors/gerror"
)
// 简单协议: (方法覆盖)发送数据
@ -46,9 +44,7 @@ func (c *PoolConn) RecvPkgWithTimeout(timeout time.Duration, option ...PkgOption
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
return nil, err
}
defer func() {
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
defer c.SetRecvDeadline(time.Time{})
data, err = c.RecvPkg(option...)
return
}
@ -58,9 +54,7 @@ func (c *PoolConn) SendPkgWithTimeout(data []byte, timeout time.Duration, option
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
return err
}
defer func() {
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
defer c.SetSendDeadline(time.Time{})
err = c.SendPkg(data, option...)
return
}

View File

@ -10,8 +10,6 @@ import (
"io"
"net"
"time"
"github.com/gogf/gf/errors/gerror"
)
// Conn handles the UDP connection.
@ -183,9 +181,7 @@ func (c *Conn) RecvWithTimeout(length int, timeout time.Duration, retry ...Retry
if err := c.SetRecvDeadline(time.Now().Add(timeout)); err != nil {
return nil, err
}
defer func() {
err = gerror.Wrap(c.SetRecvDeadline(time.Time{}), "SetRecvDeadline error")
}()
defer c.SetRecvDeadline(time.Time{})
data, err = c.Recv(length, retry...)
return
}
@ -195,9 +191,7 @@ func (c *Conn) SendWithTimeout(data []byte, timeout time.Duration, retry ...Retr
if err := c.SetSendDeadline(time.Now().Add(timeout)); err != nil {
return err
}
defer func() {
err = gerror.Wrap(c.SetSendDeadline(time.Time{}), "SetSendDeadline error")
}()
defer c.SetSendDeadline(time.Time{})
err = c.Send(data, retry...)
return
}