From 7b1081a73fe4559697f4fb5a44261fbdc1d130b2 Mon Sep 17 00:00:00 2001 From: songjiayang Date: Fri, 22 Feb 2019 14:20:24 +0800 Subject: [PATCH 1/2] issue_1721: fix render writeHeaders to make it the same as http.Header.Set (#1722) --- render/reader.go | 4 ++-- render/render_test.go | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/render/reader.go b/render/reader.go index ab60e53a..312af741 100644 --- a/render/reader.go +++ b/render/reader.go @@ -36,8 +36,8 @@ func (r Reader) WriteContentType(w http.ResponseWriter) { func (r Reader) writeHeaders(w http.ResponseWriter, headers map[string]string) { header := w.Header() for k, v := range headers { - if val := header[k]; len(val) == 0 { - header[k] = []string{v} + if header.Get(k) == "" { + header.Set(k, v) } } } diff --git a/render/render_test.go b/render/render_test.go index 3df04a17..76e29eeb 100644 --- a/render/render_test.go +++ b/render/render_test.go @@ -470,6 +470,7 @@ func TestRenderReader(t *testing.T) { body := "#!PNG some raw data" headers := make(map[string]string) headers["Content-Disposition"] = `attachment; filename="filename.png"` + headers["x-request-id"] = "requestId" err := (Reader{ ContentLength: int64(len(body)), @@ -483,4 +484,5 @@ func TestRenderReader(t *testing.T) { assert.Equal(t, "image/png", w.Header().Get("Content-Type")) assert.Equal(t, strconv.Itoa(len(body)), w.Header().Get("Content-Length")) assert.Equal(t, headers["Content-Disposition"], w.Header().Get("Content-Disposition")) + assert.Equal(t, headers["x-request-id"], w.Header().Get("x-request-id")) } From e6288e90eb313122410bf1335d502a062c1ae610 Mon Sep 17 00:00:00 2001 From: Sai Date: Fri, 22 Feb 2019 17:48:55 +0900 Subject: [PATCH 2/2] Change color methods in using defaultLogger function to public (#1771) Fix https://github.com/gin-gonic/gin/issues/1768 --- logger.go | 85 ++++++++++++++++++++++++++++---------------------- logger_test.go | 19 +++++++++++ 2 files changed, 67 insertions(+), 37 deletions(-) diff --git a/logger.go b/logger.go index bd28a11c..dc639975 100644 --- a/logger.go +++ b/logger.go @@ -68,13 +68,58 @@ type LogFormatterParams struct { BodySize int } +// StatusCodeColor is the ANSI color for appropriately logging http status code to a terminal. +func (p *LogFormatterParams) StatusCodeColor() string { + code := p.StatusCode + + switch { + case code >= http.StatusOK && code < http.StatusMultipleChoices: + return green + case code >= http.StatusMultipleChoices && code < http.StatusBadRequest: + return white + case code >= http.StatusBadRequest && code < http.StatusInternalServerError: + return yellow + default: + return red + } +} + +// MethodColor is the ANSI color for appropriately logging http method to a terminal. +func (p *LogFormatterParams) MethodColor() string { + method := p.Method + + switch method { + case "GET": + return blue + case "POST": + return cyan + case "PUT": + return yellow + case "DELETE": + return red + case "PATCH": + return green + case "HEAD": + return magenta + case "OPTIONS": + return white + default: + return reset + } +} + +// ResetColor resets all escape attributes. +func (p *LogFormatterParams) ResetColor() string { + return reset +} + // defaultLogFormatter is the default log format function Logger middleware uses. var defaultLogFormatter = func(param LogFormatterParams) string { var statusColor, methodColor, resetColor string if param.IsTerm { - statusColor = colorForStatus(param.StatusCode) - methodColor = colorForMethod(param.Method) - resetColor = reset + statusColor = param.StatusCodeColor() + methodColor = param.MethodColor() + resetColor = param.ResetColor() } return fmt.Sprintf("[GIN] %v |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s", @@ -205,37 +250,3 @@ func LoggerWithConfig(conf LoggerConfig) HandlerFunc { } } } - -func colorForStatus(code int) string { - switch { - case code >= http.StatusOK && code < http.StatusMultipleChoices: - return green - case code >= http.StatusMultipleChoices && code < http.StatusBadRequest: - return white - case code >= http.StatusBadRequest && code < http.StatusInternalServerError: - return yellow - default: - return red - } -} - -func colorForMethod(method string) string { - switch method { - case "GET": - return blue - case "POST": - return cyan - case "PUT": - return yellow - case "DELETE": - return red - case "PATCH": - return green - case "HEAD": - return magenta - case "OPTIONS": - return white - default: - return reset - } -} diff --git a/logger_test.go b/logger_test.go index 8770b5fb..c551677a 100644 --- a/logger_test.go +++ b/logger_test.go @@ -257,6 +257,13 @@ func TestDefaultLogFormatter(t *testing.T) { } func TestColorForMethod(t *testing.T) { + colorForMethod := func(method string) string { + p := LogFormatterParams{ + Method: method, + } + return p.MethodColor() + } + assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 52, 109}), colorForMethod("GET"), "get should be blue") assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 54, 109}), colorForMethod("POST"), "post should be cyan") assert.Equal(t, string([]byte{27, 91, 57, 48, 59, 52, 51, 109}), colorForMethod("PUT"), "put should be yellow") @@ -268,12 +275,24 @@ func TestColorForMethod(t *testing.T) { } func TestColorForStatus(t *testing.T) { + colorForStatus := func(code int) string { + p := LogFormatterParams{ + StatusCode: code, + } + return p.StatusCodeColor() + } + assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 50, 109}), colorForStatus(http.StatusOK), "2xx should be green") assert.Equal(t, string([]byte{27, 91, 57, 48, 59, 52, 55, 109}), colorForStatus(http.StatusMovedPermanently), "3xx should be white") assert.Equal(t, string([]byte{27, 91, 57, 48, 59, 52, 51, 109}), colorForStatus(http.StatusNotFound), "4xx should be yellow") assert.Equal(t, string([]byte{27, 91, 57, 55, 59, 52, 49, 109}), colorForStatus(2), "other things should be red") } +func TestResetColor(t *testing.T) { + p := LogFormatterParams{} + assert.Equal(t, string([]byte{27, 91, 48, 109}), p.ResetColor()) +} + func TestErrorLogger(t *testing.T) { router := New() router.Use(ErrorLogger())