httpserver: support more file types of custom error page (#3196)

Co-authored-by: Aapeli.Smith <aapelismith@users.noreply.github.com>
This commit is contained in:
Aapeli.Smith 2020-04-13 23:58:56 +08:00 committed by GitHub
parent 891446d063
commit 3b4f7a3c81
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 2 deletions

View File

@ -18,8 +18,10 @@ package errors
import ( import (
"fmt" "fmt"
"io" "io"
"mime"
"net/http" "net/http"
"os" "os"
"path/filepath"
"runtime" "runtime"
"strings" "strings"
@ -83,9 +85,13 @@ func (h ErrorHandler) errorPage(w http.ResponseWriter, r *http.Request, code int
return return
} }
defer errorPage.Close() defer errorPage.Close()
// Get content type by extension
contentType := mime.TypeByExtension(filepath.Ext(pagePath))
if contentType == "" {
contentType = "text/html; charset=utf-8"
}
// Copy the page body into the response // Copy the page body into the response
w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Content-Type", contentType)
w.WriteHeader(code) w.WriteHeader(code)
_, err = io.Copy(w, errorPage) _, err = io.Copy(w, errorPage)

View File

@ -167,6 +167,7 @@ func TestVisibleErrorWithPanic(t *testing.T) {
func TestGenericErrorPage(t *testing.T) { func TestGenericErrorPage(t *testing.T) {
// create temporary generic error page // create temporary generic error page
const genericErrorContent = "This is a generic error page" const genericErrorContent = "This is a generic error page"
const badRequestErrorJSONContent = `{"message":"This is a error json message"}`
genericErrorPagePath, err := createErrorPageFile("generic_error_test.html", genericErrorContent) genericErrorPagePath, err := createErrorPageFile("generic_error_test.html", genericErrorContent)
if err != nil { if err != nil {
@ -183,11 +184,18 @@ func TestGenericErrorPage(t *testing.T) {
} }
defer os.Remove(notFoundErrorPagePath) defer os.Remove(notFoundErrorPagePath)
badRequestErrorJSONPath, err := createErrorPageFile("not_found.json", badRequestErrorJSONContent)
if err != nil {
t.Fatal(err)
}
defer os.Remove(badRequestErrorJSONPath)
buf := bytes.Buffer{} buf := bytes.Buffer{}
em := ErrorHandler{ em := ErrorHandler{
GenericErrorPage: genericErrorPagePath, GenericErrorPage: genericErrorPagePath,
ErrorPages: map[int]string{ ErrorPages: map[int]string{
http.StatusNotFound: notFoundErrorPagePath, http.StatusNotFound: notFoundErrorPagePath,
http.StatusBadRequest:badRequestErrorJSONPath,
}, },
Log: httpserver.NewTestLogger(&buf), Log: httpserver.NewTestLogger(&buf),
} }
@ -198,6 +206,7 @@ func TestGenericErrorPage(t *testing.T) {
expectedBody string expectedBody string
expectedLog string expectedLog string
expectedErr error expectedErr error
expectedContentType string
}{ }{
{ {
next: genErrorHandler(http.StatusNotFound, nil, ""), next: genErrorHandler(http.StatusNotFound, nil, ""),
@ -205,6 +214,15 @@ func TestGenericErrorPage(t *testing.T) {
expectedBody: notFoundErrorContent, expectedBody: notFoundErrorContent,
expectedLog: "", expectedLog: "",
expectedErr: nil, expectedErr: nil,
expectedContentType: "text/html; charset=utf-8",
},
{
next: genErrorHandler(http.StatusBadRequest, nil, ""),
expectedCode: 0,
expectedBody: badRequestErrorJSONContent,
expectedLog: "",
expectedErr: nil,
expectedContentType: "application/json",
}, },
{ {
next: genErrorHandler(http.StatusInternalServerError, nil, ""), next: genErrorHandler(http.StatusInternalServerError, nil, ""),
@ -212,6 +230,7 @@ func TestGenericErrorPage(t *testing.T) {
expectedBody: genericErrorContent, expectedBody: genericErrorContent,
expectedLog: "", expectedLog: "",
expectedErr: nil, expectedErr: nil,
expectedContentType:"text/html; charset=utf-8",
}, },
} }
@ -238,6 +257,10 @@ func TestGenericErrorPage(t *testing.T) {
t.Errorf("Test %d: Expected body %q, but got %q", t.Errorf("Test %d: Expected body %q, but got %q",
i, test.expectedBody, body) i, test.expectedBody, body)
} }
if contentType := rec.Header().Get("Content-Type"); contentType != test.expectedContentType{
t.Errorf("Test %d: Expected Content-Type %s, but got %s",
i, test.expectedContentType, contentType)
}
if log := buf.String(); !strings.Contains(log, test.expectedLog) { if log := buf.String(); !strings.Contains(log, test.expectedLog) {
t.Errorf("Test %d: Expected log %q, but got %q", t.Errorf("Test %d: Expected log %q, but got %q",
i, test.expectedLog, log) i, test.expectedLog, log)