/
tester.go
85 lines (74 loc) · 2.3 KB
/
tester.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
package service
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
// TesterHandler is the entry func of the application.
func TesterHandler(targetArr []TargetConfig, notifierConfig NotifierConfig) string {
byteData, _ := json.Marshal(doRequestTest(targetArr, notifierConfig))
return string(byteData)
}
// Asynchronously request all target and report errors.
func doRequestTest(targetArr []TargetConfig, notifierConfig NotifierConfig) []Result {
if len(targetArr) == 0 {
return nil
}
httpClient := &http.Client{}
ch := make(chan Result, len(targetArr))
counter := make(chan int, len(targetArr))
for _, targetConfig := range targetArr {
currentTargetConfig := targetConfig
go func() {
proxyReq, err := http.NewRequest(http.MethodGet, currentTargetConfig.URL, nil)
if err != nil {
log.Panic(err)
}
proxyReq.Header = make(http.Header)
proxyReq.Header.Set("user-agent", "url-tester-func BOT")
if currentTargetConfig.IgnoreAnalysis {
proxyReq.Header.Set("analysis-action", "ignore")
}
resp, err := httpClient.Do(proxyReq)
if err != nil {
msg := fmt.Sprintf("Failed to test URL %s due to error %s", currentTargetConfig.URL, err)
sendAlertMsg(msg, currentTargetConfig.NotifyMethod, notifierConfig)
ch <- Result{URL: currentTargetConfig.URL, Msg: msg, Succeed: false}
counter <- 1
return
}
if resp.StatusCode != currentTargetConfig.ExpectedStatusCode {
msg := fmt.Sprintf("Failed to test URL %s due to status code is %d rather than %d",
currentTargetConfig.URL, resp.StatusCode, currentTargetConfig.ExpectedStatusCode)
sendAlertMsg(msg, currentTargetConfig.NotifyMethod, notifierConfig)
ch <- Result{URL: currentTargetConfig.URL, Msg: msg, Succeed: false}
counter <- 1
return
}
ch <- Result{URL: currentTargetConfig.URL, Msg: "", Succeed: true}
counter <- 1
defer resp.Body.Close()
}()
}
var result []Result
go func() {
sum := 0
for v := range counter {
sum += v
if sum == len(targetArr) {
close(ch)
close(counter)
}
}
}()
for v := range ch {
result = append(result, v)
}
return result
}
// Send alert via specified notifier.
func sendAlertMsg(msgToSend string, notifierType string, notifierConfig NotifierConfig) {
notifier := GetNotifierByType(notifierType)
notifier.Notify(msgToSend, notifierConfig)
}