瀏覽代碼

Refactor monitor: allow insecure requests & use of simple icons

Svilen Markov 1 年之前
父節點
當前提交
21fd842bde
共有 4 個文件被更改,包括 60 次插入34 次删除
  1. 4 4
      internal/assets/templates/monitor.html
  2. 26 7
      internal/feed/monitor.go
  3. 13 1
      internal/feed/requests.go
  4. 17 22
      internal/widget/monitor.go

+ 4 - 4
internal/assets/templates/monitor.html

@@ -22,13 +22,13 @@
 
 
 {{ define "site" }}
 {{ define "site" }}
 {{ if .IconUrl }}
 {{ if .IconUrl }}
-<img class="monitor-site-icon" src="{{ .IconUrl }}" alt="" loading="lazy">
+<img class="monitor-site-icon{{ if .IsSimpleIcon }} simple-icon{{ end }}" src="{{ .IconUrl }}" alt="" loading="lazy">
 {{ end }}
 {{ end }}
 <div>
 <div>
-    <a class="size-h3 color-highlight" href="{{ .Url }}" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
+    <a class="size-h3 color-highlight" href="{{ .URL }}" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
     <ul class="list-horizontal-text">
     <ul class="list-horizontal-text">
         {{ if not .Status.Error }}
         {{ if not .Status.Error }}
-        <li>{{ .StatusText }}</li>
+        <li title="{{ .Status.Code }}">{{ .StatusText }}</li>
         <li>{{ .Status.ResponseTime.Milliseconds | formatNumber }}ms</li>
         <li>{{ .Status.ResponseTime.Milliseconds | formatNumber }}ms</li>
         {{ else if .Status.TimedOut }}
         {{ else if .Status.TimedOut }}
         <li class="color-negative">Timed Out</li>
         <li class="color-negative">Timed Out</li>
@@ -37,7 +37,7 @@
         {{ end }}
         {{ end }}
     </ul>
     </ul>
 </div>
 </div>
-{{ if eq .StatusStyle "good" }}
+{{ if eq .StatusStyle "ok" }}
 <div class="monitor-site-status-icon">
 <div class="monitor-site-status-icon">
     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--color-positive)">
     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--color-positive)">
         <path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" clip-rule="evenodd" />
         <path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" clip-rule="evenodd" />

+ 26 - 7
internal/feed/monitor.go

@@ -7,6 +7,11 @@ import (
 	"time"
 	"time"
 )
 )
 
 
+type SiteStatusRequest struct {
+	URL           string `yaml:"url"`
+	AllowInsecure bool   `yaml:"allow-insecure"`
+}
+
 type SiteStatus struct {
 type SiteStatus struct {
 	Code         int
 	Code         int
 	TimedOut     bool
 	TimedOut     bool
@@ -14,14 +19,28 @@ type SiteStatus struct {
 	Error        error
 	Error        error
 }
 }
 
 
-func getSiteStatusTask(request *http.Request) (SiteStatus, error) {
+func getSiteStatusTask(statusRequest *SiteStatusRequest) (SiteStatus, error) {
+	request, err := http.NewRequest(http.MethodGet, statusRequest.URL, nil)
+
+	if err != nil {
+		return SiteStatus{
+			Error: err,
+		}, nil
+	}
+
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
 	ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
 	defer cancel()
 	defer cancel()
 	request = request.WithContext(ctx)
 	request = request.WithContext(ctx)
-	start := time.Now()
-	response, err := http.DefaultClient.Do(request)
-	took := time.Since(start)
-	status := SiteStatus{ResponseTime: took}
+	requestSentAt := time.Now()
+	var response *http.Response
+
+	if !statusRequest.AllowInsecure {
+		response, err = defaultClient.Do(request)
+	} else {
+		response, err = defaultInsecureClient.Do(request)
+	}
+
+	status := SiteStatus{ResponseTime: time.Since(requestSentAt)}
 
 
 	if err != nil {
 	if err != nil {
 		if errors.Is(err, context.DeadlineExceeded) {
 		if errors.Is(err, context.DeadlineExceeded) {
@@ -29,7 +48,7 @@ func getSiteStatusTask(request *http.Request) (SiteStatus, error) {
 		}
 		}
 
 
 		status.Error = err
 		status.Error = err
-		return status, err
+		return status, nil
 	}
 	}
 
 
 	defer response.Body.Close()
 	defer response.Body.Close()
@@ -39,7 +58,7 @@ func getSiteStatusTask(request *http.Request) (SiteStatus, error) {
 	return status, nil
 	return status, nil
 }
 }
 
 
-func FetchStatusesForRequests(requests []*http.Request) ([]SiteStatus, error) {
+func FetchStatusForSites(requests []*SiteStatusRequest) ([]SiteStatus, error) {
 	job := newJob(getSiteStatusTask, requests).withWorkers(20)
 	job := newJob(getSiteStatusTask, requests).withWorkers(20)
 	results, _, err := workerPoolDo(job)
 	results, _, err := workerPoolDo(job)
 
 

+ 13 - 1
internal/feed/requests.go

@@ -2,6 +2,7 @@ package feed
 
 
 import (
 import (
 	"context"
 	"context"
+	"crypto/tls"
 	"encoding/json"
 	"encoding/json"
 	"encoding/xml"
 	"encoding/xml"
 	"fmt"
 	"fmt"
@@ -11,8 +12,19 @@ import (
 	"time"
 	"time"
 )
 )
 
 
+const defaultClientTimeout = 5 * time.Second
+
 var defaultClient = &http.Client{
 var defaultClient = &http.Client{
-	Timeout: 5 * time.Second,
+	Timeout: defaultClientTimeout,
+}
+
+var insecureClientTransport = &http.Transport{
+	TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+}
+
+var defaultInsecureClient = &http.Client{
+	Timeout:   defaultClientTimeout,
+	Transport: insecureClientTransport,
 }
 }
 
 
 type RequestDoer interface {
 type RequestDoer interface {

+ 17 - 22
internal/widget/monitor.go

@@ -2,9 +2,7 @@ package widget
 
 
 import (
 import (
 	"context"
 	"context"
-	"fmt"
 	"html/template"
 	"html/template"
-	"net/http"
 	"strconv"
 	"strconv"
 	"time"
 	"time"
 
 
@@ -37,22 +35,23 @@ func statusCodeToText(status int) string {
 
 
 func statusCodeToStyle(status int) string {
 func statusCodeToStyle(status int) string {
 	if status == 200 {
 	if status == 200 {
-		return "good"
+		return "ok"
 	}
 	}
 
 
-	return "bad"
+	return "error"
 }
 }
 
 
 type Monitor struct {
 type Monitor struct {
 	widgetBase `yaml:",inline"`
 	widgetBase `yaml:",inline"`
 	Sites      []struct {
 	Sites      []struct {
-		Title       string            `yaml:"title"`
-		Url         OptionalEnvString `yaml:"url"`
-		IconUrl     string            `yaml:"icon"`
-		SameTab     bool              `yaml:"same-tab"`
-		Status      *feed.SiteStatus  `yaml:"-"`
-		StatusText  string            `yaml:"-"`
-		StatusStyle string            `yaml:"-"`
+		*feed.SiteStatusRequest `yaml:",inline"`
+		Status                  *feed.SiteStatus `yaml:"-"`
+		Title                   string           `yaml:"title"`
+		IconUrl                 string           `yaml:"icon"`
+		IsSimpleIcon            bool             `yaml:"-"`
+		SameTab                 bool             `yaml:"same-tab"`
+		StatusText              string           `yaml:"-"`
+		StatusStyle             string           `yaml:"-"`
 	} `yaml:"sites"`
 	} `yaml:"sites"`
 	Style string `yaml:"style"`
 	Style string `yaml:"style"`
 }
 }
@@ -60,25 +59,21 @@ type Monitor struct {
 func (widget *Monitor) Initialize() error {
 func (widget *Monitor) Initialize() error {
 	widget.withTitle("Monitor").withCacheDuration(5 * time.Minute)
 	widget.withTitle("Monitor").withCacheDuration(5 * time.Minute)
 
 
+	for i := range widget.Sites {
+		widget.Sites[i].IconUrl, widget.Sites[i].IsSimpleIcon = toSimpleIconIfPrefixed(widget.Sites[i].IconUrl)
+	}
+
 	return nil
 	return nil
 }
 }
 
 
 func (widget *Monitor) Update(ctx context.Context) {
 func (widget *Monitor) Update(ctx context.Context) {
-	requests := make([]*http.Request, len(widget.Sites))
+	requests := make([]*feed.SiteStatusRequest, len(widget.Sites))
 
 
 	for i := range widget.Sites {
 	for i := range widget.Sites {
-		request, err := http.NewRequest("GET", string(widget.Sites[i].Url), nil)
-
-		if err != nil {
-			message := fmt.Errorf("failed to create http request for %s: %s", widget.Sites[i].Url, err)
-			widget.withNotice(message)
-			continue
-		}
-
-		requests[i] = request
+		requests[i] = widget.Sites[i].SiteStatusRequest
 	}
 	}
 
 
-	statuses, err := feed.FetchStatusesForRequests(requests)
+	statuses, err := feed.FetchStatusForSites(requests)
 
 
 	if !widget.canContinueUpdateAfterHandlingErr(err) {
 	if !widget.canContinueUpdateAfterHandlingErr(err) {
 		return
 		return