add some parameters to config for supporting #1936 (#1956)

* add some parameters to config for supporting #1936

* remove go:embed

* apply code review  - 1956#issuecomment-1169811117

* lint

Co-authored-by: Muhammed Efe Çetin <efectn@protonmail.com>
This commit is contained in:
Majid Taheri(I love optimization) 2022-07-05 16:04:32 +04:30 committed by GitHub
parent 29be2338e8
commit 744e4da3ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 130 additions and 22 deletions

View File

@ -53,7 +53,7 @@ type Config struct {
// Optional. Default: 3 seconds // Optional. Default: 3 seconds
Refresh time.Duration Refresh time.Duration
// To disable serving HTML, you can make true this option. // Whether the service should expose only the monitoring API.
// //
// Optional. Default: false // Optional. Default: false
APIOnly bool APIOnly bool
@ -62,6 +62,23 @@ type Config struct {
// //
// Optional. Default: nil // Optional. Default: nil
Next func(c *fiber.Ctx) bool Next func(c *fiber.Ctx) bool
// Custom HTML Code to Head Section(Before End)
//
// Optional. Default: empty
CustomHead string
// FontURL for specify font resource path or URL . also you can use relative path
//
// Optional. Default: https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap
FontURL string
// ChartJsURL for specify ChartJS library path or URL . also you can use relative path
//
// Optional. Default: https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js
ChartJsURL string
} }
``` ```
@ -73,5 +90,9 @@ var ConfigDefault = Config{
Refresh: 3 * time.Second, Refresh: 3 * time.Second,
APIOnly: false, APIOnly: false,
Next: nil, Next: nil,
CustomHead:"",
FontURL:"https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap",
ChartJsURL:"https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js"
} }
``` ```

View File

@ -28,28 +28,49 @@ type Config struct {
// Optional. Default: nil // Optional. Default: nil
Next func(c *fiber.Ctx) bool Next func(c *fiber.Ctx) bool
// customized indexHtml // Custom HTML Code to Head Section(Before End)
//
// Optional. Default: empty
CustomHead string
// FontURL for specify font resource path or URL . also you can use relative path
//
// Optional. Default: https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap
FontURL string
// ChartJsURL for specify ChartJS library path or URL . also you can use relative path
//
// Optional. Default: https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js
ChartJsURL string
index string index string
} }
var ConfigDefault = Config{ var ConfigDefault = Config{
Title: defaultTitle, Title: defaultTitle,
Refresh: defaultRefresh, Refresh: defaultRefresh,
APIOnly: false, FontURL: defaultFontURL,
Next: nil, ChartJsURL: defaultChartJsURL,
index: newIndex(defaultTitle, defaultRefresh), CustomHead: defaultCustomHead,
APIOnly: false,
Next: nil,
index: newIndex(viewBag{defaultTitle, defaultRefresh, defaultFontURL, defaultChartJsURL,
defaultCustomHead}),
} }
func configDefault(config ...Config) Config { func configDefault(config ...Config) Config {
// Users can change ConfigDefault.Title/Refresh which then // Users can change ConfigDefault.Title/Refresh which then
// become incompatible with ConfigDefault.index // become incompatible with ConfigDefault.index
if ConfigDefault.Title != defaultTitle || ConfigDefault.Refresh != defaultRefresh { if ConfigDefault.Title != defaultTitle || ConfigDefault.Refresh != defaultRefresh ||
ConfigDefault.FontURL != defaultFontURL || ConfigDefault.ChartJsURL != defaultChartJsURL ||
ConfigDefault.CustomHead != defaultCustomHead {
if ConfigDefault.Refresh < minRefresh { if ConfigDefault.Refresh < minRefresh {
ConfigDefault.Refresh = minRefresh ConfigDefault.Refresh = minRefresh
} }
// update default index with new default title/refresh // update default index with new default title/refresh
ConfigDefault.index = newIndex(ConfigDefault.Title, ConfigDefault.Refresh) ConfigDefault.index = newIndex(viewBag{ConfigDefault.Title,
ConfigDefault.Refresh, ConfigDefault.FontURL, ConfigDefault.ChartJsURL, ConfigDefault.CustomHead})
} }
// Return default config if nothing provided // Return default config if nothing provided
@ -68,7 +89,13 @@ func configDefault(config ...Config) Config {
if cfg.Refresh == 0 { if cfg.Refresh == 0 {
cfg.Refresh = ConfigDefault.Refresh cfg.Refresh = ConfigDefault.Refresh
} }
if cfg.FontURL == "" {
cfg.FontURL = defaultFontURL
}
if cfg.ChartJsURL == "" {
cfg.ChartJsURL = defaultChartJsURL
}
if cfg.Title == ConfigDefault.Title && cfg.Refresh == ConfigDefault.Refresh { if cfg.Title == ConfigDefault.Title && cfg.Refresh == ConfigDefault.Refresh {
cfg.index = ConfigDefault.index cfg.index = ConfigDefault.index
} else { } else {
@ -76,7 +103,8 @@ func configDefault(config ...Config) Config {
cfg.Refresh = minRefresh cfg.Refresh = minRefresh
} }
// update cfg.index with custom title/refresh // update cfg.index with custom title/refresh
cfg.index = newIndex(cfg.Title, cfg.Refresh) cfg.index = newIndex(viewBag{cfg.Title,
cfg.Refresh, cfg.FontURL, cfg.ChartJsURL, cfg.CustomHead})
} }
if cfg.Next == nil { if cfg.Next == nil {

View File

@ -6,25 +6,37 @@ import (
"time" "time"
) )
// returns index with new title/refresh type viewBag struct {
func newIndex(title string, refresh time.Duration) string { title string
refresh time.Duration
fontUrl string
chartJsUrl string
customHead string
}
timeout := refresh.Milliseconds() - timeoutDiff // returns index with new title/refresh
func newIndex(dat viewBag) string {
timeout := dat.refresh.Milliseconds() - timeoutDiff
if timeout < timeoutDiff { if timeout < timeoutDiff {
timeout = timeoutDiff timeout = timeoutDiff
} }
ts := strconv.FormatInt(timeout, 10) ts := strconv.FormatInt(timeout, 10)
replacer := strings.NewReplacer("$TITLE", dat.title, "$TIMEOUT", ts,
index := strings.ReplaceAll(indexHtml, "$TITLE", title) "$FONT_URL", dat.fontUrl, "$CHART_JS_URL", dat.chartJsUrl, "$CUSTOM_HEAD", dat.customHead,
return strings.ReplaceAll(index, "$TIMEOUT", ts) )
return replacer.Replace(indexHtml)
} }
const ( const (
defaultTitle = "Fiber Monitor" defaultTitle = "Fiber Monitor"
defaultRefresh = 3 * time.Second defaultRefresh = 3 * time.Second
timeoutDiff = 200 // timeout will be Refresh (in millisconds) - timeoutDiff timeoutDiff = 200 // timeout will be Refresh (in milliseconds) - timeoutDiff
minRefresh = timeoutDiff * time.Millisecond minRefresh = timeoutDiff * time.Millisecond
defaultFontURL = `https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap`
defaultChartJsURL = `https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js`
defaultCustomHead = ``
// parametrized by $TITLE and $TIMEOUT // parametrized by $TITLE and $TIMEOUT
indexHtml = `<!DOCTYPE html> indexHtml = `<!DOCTYPE html>
@ -32,8 +44,9 @@ const (
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap" rel="stylesheet"> <link href="$FONT_URL" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.9/dist/Chart.bundle.min.js"></script> <script src="$CHART_JS_URL"></script>
<title>$TITLE</title> <title>$TITLE</title>
<style> <style>
body { body {
@ -80,6 +93,7 @@ const (
width: 200px; width: 200px;
height: 180px; height: 180px;
} }
$CUSTOM_HEAD
</style> </style>
</head> </head>
<body> <body>
@ -253,5 +267,6 @@ const (
fetchJSON() fetchJSON()
</script> </script>
</body> </body>
</html>` </html>
`
) )

View File

@ -61,6 +61,50 @@ func Test_Monitor_Html(t *testing.T) {
conf.Refresh.Milliseconds()-timeoutDiff) conf.Refresh.Milliseconds()-timeoutDiff)
utils.AssertEqual(t, true, bytes.Contains(buf, []byte(timeoutLine))) utils.AssertEqual(t, true, bytes.Contains(buf, []byte(timeoutLine)))
} }
func Test_Monitor_Html_CustomCodes(t *testing.T) {
t.Parallel()
app := fiber.New()
// defaults
app.Get("/", New())
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
utils.AssertEqual(t, fiber.MIMETextHTMLCharsetUTF8,
resp.Header.Get(fiber.HeaderContentType))
buf, err := ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, bytes.Contains(buf, []byte("<title>"+defaultTitle+"</title>")))
timeoutLine := fmt.Sprintf("setTimeout(fetchJSON, %d)",
defaultRefresh.Milliseconds()-timeoutDiff)
utils.AssertEqual(t, true, bytes.Contains(buf, []byte(timeoutLine)))
// custom config
conf := Config{Title: "New " + defaultTitle, Refresh: defaultRefresh + time.Second,
ChartJsURL: "https://cdnjs.com/libraries/Chart.js",
FontURL: "/public/my-font.css",
CustomHead: `<style>body{background:#fff}</style>`,
}
app.Get("/custom", New(conf))
resp, err = app.Test(httptest.NewRequest(fiber.MethodGet, "/custom", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
utils.AssertEqual(t, fiber.MIMETextHTMLCharsetUTF8,
resp.Header.Get(fiber.HeaderContentType))
buf, err = ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, bytes.Contains(buf, []byte("<title>"+conf.Title+"</title>")))
utils.AssertEqual(t, true, bytes.Contains(buf, []byte("https://cdnjs.com/libraries/Chart.js")))
utils.AssertEqual(t, true, bytes.Contains(buf, []byte("/public/my-font.css")))
utils.AssertEqual(t, true, bytes.Contains(buf, []byte(conf.CustomHead)))
timeoutLine = fmt.Sprintf("setTimeout(fetchJSON, %d)",
conf.Refresh.Milliseconds()-timeoutDiff)
utils.AssertEqual(t, true, bytes.Contains(buf, []byte(timeoutLine)))
}
// go test -run Test_Monitor_JSON -race // go test -run Test_Monitor_JSON -race
func Test_Monitor_JSON(t *testing.T) { func Test_Monitor_JSON(t *testing.T) {