Merge branch 'master' into modular-deps

This commit is contained in:
Antoine GIRARD 2019-04-29 16:42:57 +02:00 committed by GitHub
commit fce78a69e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 5 deletions

View File

@ -1696,9 +1696,9 @@ func main() {
// Wait for interrupt signal to gracefully shutdown the server with // Wait for interrupt signal to gracefully shutdown the server with
// a timeout of 5 seconds. // a timeout of 5 seconds.
quit := make(chan os.Signal) quit := make(chan os.Signal)
// kill (no param) default send syscanll.SIGTERM // kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT // kill -2 is syscall.SIGINT
// kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it // kill -9 is syscall.SIGKILL but can"t be catch, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit <-quit
log.Println("Shutdown Server ...") log.Println("Shutdown Server ...")

View File

@ -118,7 +118,7 @@ func StaticFS(relativePath string, fs http.FileSystem) gin.IRoutes {
return engine().StaticFS(relativePath, fs) return engine().StaticFS(relativePath, fs)
} }
// Use attachs a global middleware to the router. ie. the middlewares attached though Use() will be // Use attaches a global middleware to the router. ie. the middlewares attached though Use() will be
// included in the handlers chain for every single request. Even 404, 405, static files... // included in the handlers chain for every single request. Even 404, 405, static files...
// For example, this is the right place for a logger or error management middleware. // For example, this is the right place for a logger or error management middleware.
func Use(middlewares ...gin.HandlerFunc) gin.IRoutes { func Use(middlewares ...gin.HandlerFunc) gin.IRoutes {
@ -153,7 +153,7 @@ func RunUnix(file string) (err error) {
// RunFd attaches the router to a http.Server and starts listening and serving HTTP requests // RunFd attaches the router to a http.Server and starts listening and serving HTTP requests
// through the specified file descriptor. // through the specified file descriptor.
// Note: thie method will block the calling goroutine indefinitely unless on error happens. // Note: the method will block the calling goroutine indefinitely unless on error happens.
func RunFd(fd int) (err error) { func RunFd(fd int) (err error) {
return engine().RunFd(fd) return engine().RunFd(fd)
} }

View File

@ -53,11 +53,18 @@ func RecoveryWithWriter(out io.Writer) HandlerFunc {
if logger != nil { if logger != nil {
stack := stack(3) stack := stack(3)
httpRequest, _ := httputil.DumpRequest(c.Request, false) httpRequest, _ := httputil.DumpRequest(c.Request, false)
headers := strings.Split(string(httpRequest), "\r\n")
for idx, header := range headers {
current := strings.Split(header, ":")
if current[0] == "Authorization" {
headers[idx] = current[0] + ": *"
}
}
if brokenPipe { if brokenPipe {
logger.Printf("%s\n%s%s", err, string(httpRequest), reset) logger.Printf("%s\n%s%s", err, string(httpRequest), reset)
} else if IsDebugging() { } else if IsDebugging() {
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s", logger.Printf("[Recovery] %s panic recovered:\n%s\n%s\n%s%s",
timeFormat(time.Now()), string(httpRequest), err, stack, reset) timeFormat(time.Now()), strings.Join(headers, "\r\n"), err, stack, reset)
} else { } else {
logger.Printf("[Recovery] %s panic recovered:\n%s\n%s%s", logger.Printf("[Recovery] %s panic recovered:\n%s\n%s%s",
timeFormat(time.Now()), err, stack, reset) timeFormat(time.Now()), err, stack, reset)

View File

@ -8,6 +8,7 @@ package gin
import ( import (
"bytes" "bytes"
"fmt"
"net" "net"
"net/http" "net/http"
"os" "os"
@ -18,6 +19,37 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestPanicClean(t *testing.T) {
buffer := new(bytes.Buffer)
router := New()
password := "my-super-secret-password"
router.Use(RecoveryWithWriter(buffer))
router.GET("/recovery", func(c *Context) {
c.AbortWithStatus(http.StatusBadRequest)
panic("Oupps, Houston, we have a problem")
})
// RUN
w := performRequest(router, "GET", "/recovery",
header{
Key: "Host",
Value: "www.google.com",
},
header{
Key: "Authorization",
Value: fmt.Sprintf("Bearer %s", password),
},
header{
Key: "Content-Type",
Value: "application/json",
},
)
// TEST
assert.Equal(t, http.StatusBadRequest, w.Code)
// Check the buffer does not have the secret key
assert.NotContains(t, buffer.String(), password)
}
// TestPanicInHandler assert that panic has been recovered. // TestPanicInHandler assert that panic has been recovered.
func TestPanicInHandler(t *testing.T) { func TestPanicInHandler(t *testing.T) {
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)