mirror of
https://github.com/oneclickvirt/ecs.git
synced 2025-09-30 21:22:11 +08:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ecd61fd51b | ||
![]() |
3c800b5193 | ||
![]() |
861a8f46e4 | ||
![]() |
6f0b1556bb | ||
![]() |
ab91735695 | ||
![]() |
c611946a9c | ||
![]() |
6a0fe661fa | ||
![]() |
dd20c72910 | ||
![]() |
0de20a290f | ||
![]() |
b4ba95b3f6 | ||
![]() |
b33b588ea4 | ||
![]() |
9d214e2b8f |
@@ -1,4 +1,4 @@
|
|||||||
package basic
|
package basic1
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package basic
|
package basic1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@@ -10,7 +10,7 @@ import (
|
|||||||
// 使用gopsutil查询可能会特别慢,执行命令查询反而更快
|
// 使用gopsutil查询可能会特别慢,执行命令查询反而更快
|
||||||
// TODO
|
// TODO
|
||||||
// 迁移Shell的完整检测逻辑使用执行命令的方式查询,最后都失败才使用gopsutil查询
|
// 迁移Shell的完整检测逻辑使用执行命令的方式查询,最后都失败才使用gopsutil查询
|
||||||
// 本包已在main中调用
|
// 本包不在main中使用
|
||||||
func Basic(language string) {
|
func Basic(language string) {
|
||||||
ipInfo, _, _ := network.NetworkCheck("both", false, language)
|
ipInfo, _, _ := network.NetworkCheck("both", false, language)
|
||||||
systemInfo := system.CheckSystemInfo(language)
|
systemInfo := system.CheckSystemInfo(language)
|
||||||
|
6
go.mod
6
go.mod
@@ -11,10 +11,10 @@ require (
|
|||||||
github.com/oneclickvirt/defaultset v0.0.2-20240624082446
|
github.com/oneclickvirt/defaultset v0.0.2-20240624082446
|
||||||
github.com/oneclickvirt/disktest v0.0.3-20240629152513
|
github.com/oneclickvirt/disktest v0.0.3-20240629152513
|
||||||
github.com/oneclickvirt/memorytest v0.0.1-20240624151629
|
github.com/oneclickvirt/memorytest v0.0.1-20240624151629
|
||||||
github.com/oneclickvirt/nt3 v0.0.1-20240627070009
|
github.com/oneclickvirt/nt3 v0.0.1-20240630131017
|
||||||
github.com/oneclickvirt/portchecker v0.0.1-20240624155429
|
github.com/oneclickvirt/portchecker v0.0.1-20240624155429
|
||||||
github.com/oneclickvirt/security v0.0.1-20240625075931
|
github.com/oneclickvirt/security v0.0.1-20240630101628
|
||||||
github.com/oneclickvirt/speedtest v0.0.5-20240630045424
|
github.com/oneclickvirt/speedtest v0.0.6-20240630114816
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
6
go.sum
6
go.sum
@@ -111,14 +111,20 @@ github.com/oneclickvirt/memorytest v0.0.1-20240624151629 h1:2rJAB3gFGlFPocIb/WRV
|
|||||||
github.com/oneclickvirt/memorytest v0.0.1-20240624151629/go.mod h1:+YNzy+NeVg61d0kNwSyVDqHyVtKzjuRe1NvMzsDLg0I=
|
github.com/oneclickvirt/memorytest v0.0.1-20240624151629/go.mod h1:+YNzy+NeVg61d0kNwSyVDqHyVtKzjuRe1NvMzsDLg0I=
|
||||||
github.com/oneclickvirt/nt3 v0.0.1-20240627070009 h1:020pqkdGDnkIIpyNbbS1sjG1uIl3GgjeNgVqJzAw0ng=
|
github.com/oneclickvirt/nt3 v0.0.1-20240627070009 h1:020pqkdGDnkIIpyNbbS1sjG1uIl3GgjeNgVqJzAw0ng=
|
||||||
github.com/oneclickvirt/nt3 v0.0.1-20240627070009/go.mod h1:Vb724PgpP17W09mLw5I2UZZAuYbY8WwGlKZdxRDFr0Y=
|
github.com/oneclickvirt/nt3 v0.0.1-20240627070009/go.mod h1:Vb724PgpP17W09mLw5I2UZZAuYbY8WwGlKZdxRDFr0Y=
|
||||||
|
github.com/oneclickvirt/nt3 v0.0.1-20240630131017 h1:L9PkTk8ij7J/aN6WZ4VPRc6hALfre/HyHnHj1vVNAZw=
|
||||||
|
github.com/oneclickvirt/nt3 v0.0.1-20240630131017/go.mod h1:Vb724PgpP17W09mLw5I2UZZAuYbY8WwGlKZdxRDFr0Y=
|
||||||
github.com/oneclickvirt/portchecker v0.0.1-20240624155429 h1:+wapaOcFrg1iWJDhBKThDzppyIMY7hWxK7F5RBkZg4o=
|
github.com/oneclickvirt/portchecker v0.0.1-20240624155429 h1:+wapaOcFrg1iWJDhBKThDzppyIMY7hWxK7F5RBkZg4o=
|
||||||
github.com/oneclickvirt/portchecker v0.0.1-20240624155429/go.mod h1:HQxSTrqM8/QFqHMTBZ7S8H9eEO5FkUXU1eb7ZX5Mk+k=
|
github.com/oneclickvirt/portchecker v0.0.1-20240624155429/go.mod h1:HQxSTrqM8/QFqHMTBZ7S8H9eEO5FkUXU1eb7ZX5Mk+k=
|
||||||
github.com/oneclickvirt/security v0.0.1-20240625075931 h1:Vj1Wq/JVcqYpfqUWRtsITbz3zM4HxnLC0iPxxA6akP0=
|
github.com/oneclickvirt/security v0.0.1-20240625075931 h1:Vj1Wq/JVcqYpfqUWRtsITbz3zM4HxnLC0iPxxA6akP0=
|
||||||
github.com/oneclickvirt/security v0.0.1-20240625075931/go.mod h1:6bjZjpYJ8M3aRIcLP61b0mjYRwvtWbYkvoGjS28Bdy4=
|
github.com/oneclickvirt/security v0.0.1-20240625075931/go.mod h1:6bjZjpYJ8M3aRIcLP61b0mjYRwvtWbYkvoGjS28Bdy4=
|
||||||
|
github.com/oneclickvirt/security v0.0.1-20240630101628 h1:Ain+TvrWo22ex9CGc1Z2seOX32XIXW8ajs2K3sfd+JY=
|
||||||
|
github.com/oneclickvirt/security v0.0.1-20240630101628/go.mod h1:6bjZjpYJ8M3aRIcLP61b0mjYRwvtWbYkvoGjS28Bdy4=
|
||||||
github.com/oneclickvirt/speedtest v0.0.4-20240629100548 h1:DQA0R/EdtmLJrQBb9JvQBaBpcMgiGDvIHq+0quNZQQM=
|
github.com/oneclickvirt/speedtest v0.0.4-20240629100548 h1:DQA0R/EdtmLJrQBb9JvQBaBpcMgiGDvIHq+0quNZQQM=
|
||||||
github.com/oneclickvirt/speedtest v0.0.4-20240629100548/go.mod h1:JNIxUbEJD12w81b7754RLHD55fsH6wHj+fCV2PqBDhk=
|
github.com/oneclickvirt/speedtest v0.0.4-20240629100548/go.mod h1:JNIxUbEJD12w81b7754RLHD55fsH6wHj+fCV2PqBDhk=
|
||||||
github.com/oneclickvirt/speedtest v0.0.5-20240630045424 h1:LXvoAgCAJVGci0Tzm3cDgvNaezncS8R5nOn8s+p+kNA=
|
github.com/oneclickvirt/speedtest v0.0.5-20240630045424 h1:LXvoAgCAJVGci0Tzm3cDgvNaezncS8R5nOn8s+p+kNA=
|
||||||
github.com/oneclickvirt/speedtest v0.0.5-20240630045424/go.mod h1:zd5ZgIGslmtQLQehEfRjyumlvgDHTpCSMchKfKXoASI=
|
github.com/oneclickvirt/speedtest v0.0.5-20240630045424/go.mod h1:zd5ZgIGslmtQLQehEfRjyumlvgDHTpCSMchKfKXoASI=
|
||||||
|
github.com/oneclickvirt/speedtest v0.0.6-20240630114816 h1:gI2hqV0IwcvGqYzLhlt4w2oZvYhCL+73jftUuJYBsuI=
|
||||||
|
github.com/oneclickvirt/speedtest v0.0.6-20240630114816/go.mod h1:zd5ZgIGslmtQLQehEfRjyumlvgDHTpCSMchKfKXoASI=
|
||||||
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
|
github.com/onsi/ginkgo/v2 v2.16.0 h1:7q1w9frJDzninhXxjZd+Y/x54XNjG/UlRLIYPZafsPM=
|
||||||
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
github.com/onsi/ginkgo/v2 v2.16.0/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs=
|
||||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||||
|
200
goecs.go
200
goecs.go
@@ -3,23 +3,22 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/oneclickvirt/UnlockTests/uts"
|
|
||||||
"github.com/oneclickvirt/basics/system"
|
|
||||||
"github.com/oneclickvirt/ecs/backtrace"
|
"github.com/oneclickvirt/ecs/backtrace"
|
||||||
"github.com/oneclickvirt/ecs/commediatest"
|
"github.com/oneclickvirt/ecs/commediatest"
|
||||||
"github.com/oneclickvirt/ecs/cputest"
|
"github.com/oneclickvirt/ecs/cputest"
|
||||||
"github.com/oneclickvirt/ecs/disktest"
|
"github.com/oneclickvirt/ecs/disktest"
|
||||||
"github.com/oneclickvirt/ecs/memorytest"
|
"github.com/oneclickvirt/ecs/memorytest"
|
||||||
"github.com/oneclickvirt/ecs/network"
|
|
||||||
"github.com/oneclickvirt/ecs/ntrace"
|
"github.com/oneclickvirt/ecs/ntrace"
|
||||||
"github.com/oneclickvirt/ecs/speedtest"
|
"github.com/oneclickvirt/ecs/speedtest"
|
||||||
"github.com/oneclickvirt/ecs/unlocktest"
|
"github.com/oneclickvirt/ecs/unlocktest"
|
||||||
|
"github.com/oneclickvirt/ecs/utils"
|
||||||
"github.com/oneclickvirt/portchecker/email"
|
"github.com/oneclickvirt/portchecker/email"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -35,73 +34,6 @@ var (
|
|||||||
width = 84
|
width = 84
|
||||||
)
|
)
|
||||||
|
|
||||||
func printCenteredTitle(title string, width int) {
|
|
||||||
titleLength := utf8.RuneCountInString(title) // 计算字符串的字符数
|
|
||||||
totalPadding := width - titleLength
|
|
||||||
padding := totalPadding / 2
|
|
||||||
paddingStr := strings.Repeat("-", padding)
|
|
||||||
fmt.Println(paddingStr + title + paddingStr + strings.Repeat("-", totalPadding%2))
|
|
||||||
}
|
|
||||||
|
|
||||||
func securityCheck() (string, string) {
|
|
||||||
var wgt sync.WaitGroup
|
|
||||||
var ipInfo, securityInfo, systemInfo string
|
|
||||||
go func() {
|
|
||||||
wgt.Add(1)
|
|
||||||
defer wgt.Done()
|
|
||||||
ipInfo, securityInfo, _ = network.NetworkCheck("both", true, language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
wgt.Add(1)
|
|
||||||
defer wgt.Done()
|
|
||||||
systemInfo = system.CheckSystemInfo(language)
|
|
||||||
}()
|
|
||||||
wgt.Wait()
|
|
||||||
basicInfo := systemInfo + ipInfo
|
|
||||||
if strings.Contains(ipInfo, "IPV4") && strings.Contains(ipInfo, "IPV6") {
|
|
||||||
uts.IPV4 = true
|
|
||||||
uts.IPV6 = true
|
|
||||||
if nt3CheckType == "" {
|
|
||||||
nt3CheckType = "ipv4"
|
|
||||||
}
|
|
||||||
} else if strings.Contains(ipInfo, "IPV4") {
|
|
||||||
uts.IPV4 = true
|
|
||||||
uts.IPV6 = false
|
|
||||||
if nt3CheckType == "" {
|
|
||||||
nt3CheckType = "ipv4"
|
|
||||||
}
|
|
||||||
} else if strings.Contains(ipInfo, "IPV6") {
|
|
||||||
uts.IPV6 = true
|
|
||||||
uts.IPV4 = false
|
|
||||||
if nt3CheckType == "" {
|
|
||||||
nt3CheckType = "ipv6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if nt3CheckType == "ipv4" && !strings.Contains(ipInfo, "IPV4") && strings.Contains(ipInfo, "IPV6") {
|
|
||||||
nt3CheckType = "ipv6"
|
|
||||||
} else if nt3CheckType == "ipv6" && !strings.Contains(ipInfo, "IPV6") && strings.Contains(ipInfo, "IPV4") {
|
|
||||||
nt3CheckType = "ipv4"
|
|
||||||
}
|
|
||||||
basicInfo = strings.ReplaceAll(basicInfo, "\n\n", "\n")
|
|
||||||
return basicInfo, securityInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func printHead() {
|
|
||||||
if language == "zh" {
|
|
||||||
printCenteredTitle("融合怪测试", width)
|
|
||||||
fmt.Printf("版本:%s\n", ecsVersion)
|
|
||||||
fmt.Println("测评频道: https://t.me/vps_reviews\n" +
|
|
||||||
"Go项目地址:https://github.com/oneclickvirt/ecs\n" +
|
|
||||||
"Shell项目地址:https://github.com/spiritLHLS/ecs")
|
|
||||||
} else {
|
|
||||||
printCenteredTitle("Fusion Monster Test", width)
|
|
||||||
fmt.Printf("Version: %s\n", ecsVersion)
|
|
||||||
fmt.Println("Review Channel: https://t.me/vps_reviews\n" +
|
|
||||||
"Go Project URL: https://github.com/oneclickvirt/ecs\n" +
|
|
||||||
"Shell Project URL: https://github.com/spiritLHLS/ecs")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.BoolVar(&showVersion, "v", false, "Show version information")
|
flag.BoolVar(&showVersion, "v", false, "Show version information")
|
||||||
flag.StringVar(&language, "l", "zh", "Specify language (supported: en, zh)")
|
flag.StringVar(&language, "l", "zh", "Specify language (supported: en, zh)")
|
||||||
@@ -120,104 +52,136 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
var wg sync.WaitGroup
|
var (
|
||||||
var basicInfo, securityInfo, emailInfo, mediaInfo string
|
wg sync.WaitGroup
|
||||||
if language == "zh" {
|
basicInfo, securityInfo, emailInfo, mediaInfo string
|
||||||
printHead()
|
output, tempOutput string
|
||||||
printCenteredTitle("基础信息", width)
|
)
|
||||||
basicInfo, securityInfo = securityCheck()
|
output = utils.PrintAndCapture(func() {
|
||||||
fmt.Println(basicInfo)
|
switch language {
|
||||||
printCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", cpuTestMethod), width)
|
case "zh":
|
||||||
|
utils.PrintHead(language, width, ecsVersion)
|
||||||
|
utils.PrintCenteredTitle("基础信息", width)
|
||||||
|
basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType)
|
||||||
|
fmt.Printf(basicInfo)
|
||||||
|
utils.PrintCenteredTitle(fmt.Sprintf("CPU测试-通过%s测试", cpuTestMethod), width)
|
||||||
cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
||||||
printCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", cpuTestMethod), width)
|
utils.PrintCenteredTitle(fmt.Sprintf("内存测试-通过%s测试", cpuTestMethod), width)
|
||||||
memorytest.MemoryTest(language, memoryTestMethod)
|
memorytest.MemoryTest(language, memoryTestMethod)
|
||||||
printCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", diskTestMethod), width)
|
utils.PrintCenteredTitle(fmt.Sprintf("硬盘测试-通过%s测试", diskTestMethod), width)
|
||||||
disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck)
|
disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck)
|
||||||
|
utils.PrintCenteredTitle("御三家流媒体解锁", width)
|
||||||
|
wg.Add(2)
|
||||||
go func() {
|
go func() {
|
||||||
wg.Add(1)
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
emailInfo = email.EmailCheck()
|
emailInfo = email.EmailCheck()
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
wg.Add(1)
|
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
mediaInfo = unlocktest.MediaTest(language)
|
mediaInfo = unlocktest.MediaTest(language)
|
||||||
}()
|
}()
|
||||||
printCenteredTitle("御三家流媒体解锁", width)
|
|
||||||
commediatest.ComMediaTest(language)
|
commediatest.ComMediaTest(language)
|
||||||
printCenteredTitle("跨国流媒体解锁", width)
|
utils.PrintCenteredTitle("跨国流媒体解锁", width)
|
||||||
wg.Wait()
|
wg.Wait() // 后台任务含流媒体测试和邮件测试
|
||||||
fmt.Printf(mediaInfo)
|
fmt.Printf(mediaInfo)
|
||||||
printCenteredTitle("IP质量检测", width)
|
utils.PrintCenteredTitle("IP质量检测", width)
|
||||||
fmt.Printf(securityInfo)
|
fmt.Printf(securityInfo)
|
||||||
printCenteredTitle("邮件端口检测", width)
|
utils.PrintCenteredTitle("邮件端口检测", width)
|
||||||
fmt.Println(emailInfo)
|
fmt.Println(emailInfo)
|
||||||
printCenteredTitle("三网回程", width)
|
|
||||||
backtrace.BackTrace()
|
|
||||||
if runtime.GOOS != "windows" {
|
if runtime.GOOS != "windows" {
|
||||||
|
utils.PrintCenteredTitle("三网回程", width)
|
||||||
|
backtrace.BackTrace()
|
||||||
// nexttrace 在win上不支持检测,报错 bind: An invalid argument was supplied.
|
// nexttrace 在win上不支持检测,报错 bind: An invalid argument was supplied.
|
||||||
printCenteredTitle("路由检测", width)
|
utils.PrintCenteredTitle("路由检测", width)
|
||||||
ntrace.TraceRoute3(language, nt3Location, nt3CheckType)
|
ntrace.TraceRoute3(language, nt3Location, nt3CheckType)
|
||||||
}
|
}
|
||||||
printCenteredTitle("就近节点测速", width)
|
utils.PrintCenteredTitle("就近节点测速", width)
|
||||||
speedtest.ShowHead(language)
|
speedtest.ShowHead(language)
|
||||||
speedtest.NearbySP()
|
speedtest.NearbySP()
|
||||||
speedtest.CustomSP("net", "global", 4)
|
speedtest.CustomSP("net", "global", 4)
|
||||||
speedtest.CustomSP("net", "cu", spNum)
|
speedtest.CustomSP("net", "cu", spNum)
|
||||||
speedtest.CustomSP("net", "ct", spNum)
|
speedtest.CustomSP("net", "ct", spNum)
|
||||||
speedtest.CustomSP("net", "cmcc", spNum)
|
speedtest.CustomSP("net", "cmcc", spNum)
|
||||||
printCenteredTitle("", width)
|
utils.PrintCenteredTitle("", width)
|
||||||
endTime := time.Now()
|
endTime := time.Now()
|
||||||
duration := endTime.Sub(startTime)
|
duration := endTime.Sub(startTime)
|
||||||
minutes := int(duration.Minutes())
|
minutes := int(duration.Minutes())
|
||||||
seconds := int(duration.Seconds()) % 60
|
seconds := int(duration.Seconds()) % 60
|
||||||
fmt.Printf("花费 : %d 分 %d 秒\n", minutes, seconds)
|
|
||||||
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
|
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
|
||||||
|
fmt.Printf("花费 : %d 分 %d 秒\n", minutes, seconds)
|
||||||
fmt.Printf("时间 : %s\n", currentTime)
|
fmt.Printf("时间 : %s\n", currentTime)
|
||||||
printCenteredTitle("", width)
|
utils.PrintCenteredTitle("", width)
|
||||||
} else if language == "en" {
|
case "en":
|
||||||
printHead()
|
utils.PrintHead(language, width, ecsVersion)
|
||||||
printCenteredTitle("Basic Information", width)
|
utils.PrintCenteredTitle("Basic Information", width)
|
||||||
go func() {
|
basicInfo, securityInfo, nt3CheckType = utils.SecurityCheck(language, nt3CheckType)
|
||||||
wg.Add(1)
|
|
||||||
defer wg.Done()
|
|
||||||
basicInfo, securityInfo = securityCheck()
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
fmt.Printf(basicInfo)
|
fmt.Printf(basicInfo)
|
||||||
printCenteredTitle(fmt.Sprintf("CPU Test - %s Method", cpuTestMethod), width)
|
utils.PrintCenteredTitle(fmt.Sprintf("CPU Test - %s Method", cpuTestMethod), width)
|
||||||
cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
cputest.CpuTest(language, cpuTestMethod, cpuTestThreadMode)
|
||||||
printCenteredTitle(fmt.Sprintf("Memory Test - %s Method", memoryTestMethod), width)
|
utils.PrintCenteredTitle(fmt.Sprintf("Memory Test - %s Method", memoryTestMethod), width)
|
||||||
memorytest.MemoryTest(language, memoryTestMethod)
|
utils.PrintCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width)
|
||||||
printCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width)
|
utils.PrintCenteredTitle(fmt.Sprintf("Disk Test - %s Method", diskTestMethod), width)
|
||||||
disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck)
|
disktest.DiskTest(language, diskTestMethod, diskTestPath, diskMultiCheck)
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
emailInfo = email.EmailCheck()
|
emailInfo = email.EmailCheck()
|
||||||
}()
|
}()
|
||||||
printCenteredTitle("The Three Families Streaming Media Unlock", width)
|
utils.PrintCenteredTitle("The Three Families Streaming Media Unlock", width)
|
||||||
commediatest.ComMediaTest(language)
|
commediatest.ComMediaTest(language)
|
||||||
printCenteredTitle("Cross-Border Streaming Media Unlock", width)
|
utils.PrintCenteredTitle("Cross-Border Streaming Media Unlock", width)
|
||||||
unlocktest.MediaTest(language)
|
unlocktest.MediaTest(language)
|
||||||
printCenteredTitle("IP Quality Check", width)
|
utils.PrintCenteredTitle("IP Quality Check", width)
|
||||||
fmt.Printf(securityInfo)
|
fmt.Printf(securityInfo)
|
||||||
printCenteredTitle("Email Port Check", width)
|
utils.PrintCenteredTitle("Email Port Check", width)
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
fmt.Println(emailInfo)
|
fmt.Println(emailInfo)
|
||||||
//printCenteredTitle("Return Path Routing", width)
|
//utils.PrintCenteredTitle("Return Path Routing", width)
|
||||||
printCenteredTitle("Nearby Node Speed Test", width)
|
utils.PrintCenteredTitle("Nearby Node Speed Test", width)
|
||||||
speedtest.ShowHead(language)
|
speedtest.ShowHead(language)
|
||||||
speedtest.NearbySP()
|
speedtest.NearbySP()
|
||||||
speedtest.CustomSP("net", "global", -1)
|
speedtest.CustomSP("net", "global", -1)
|
||||||
printCenteredTitle("", width)
|
utils.PrintCenteredTitle("", width)
|
||||||
endTime := time.Now()
|
endTime := time.Now()
|
||||||
duration := endTime.Sub(startTime)
|
duration := endTime.Sub(startTime)
|
||||||
minutes := int(duration.Minutes())
|
minutes := int(duration.Minutes())
|
||||||
seconds := int(duration.Seconds()) % 60
|
seconds := int(duration.Seconds()) % 60
|
||||||
fmt.Printf("Cost Time : %d 分 %d 秒\n", minutes, seconds)
|
|
||||||
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
|
currentTime := time.Now().Format("Mon Jan 2 15:04:05 MST 2006")
|
||||||
|
fmt.Printf("Cost Time : %d 分 %d 秒\n", minutes, seconds)
|
||||||
fmt.Printf("Current Time : %s\n", currentTime)
|
fmt.Printf("Current Time : %s\n", currentTime)
|
||||||
printCenteredTitle("", width)
|
utils.PrintCenteredTitle("", width)
|
||||||
|
default:
|
||||||
|
fmt.Println("Unsupported language")
|
||||||
}
|
}
|
||||||
|
}, tempOutput, output)
|
||||||
|
// 创建文件
|
||||||
|
filePath := "goecs.txt"
|
||||||
|
file, err := os.Create(filePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Can not make file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
// 将 output 写入文件
|
||||||
|
// 匹配 ANSI 转义序列
|
||||||
|
ansiRegex := regexp.MustCompile("\x1B\\[[0-9;]+[a-zA-Z]")
|
||||||
|
// 移除 ANSI 转义序列
|
||||||
|
cleanedOutput := ansiRegex.ReplaceAllString(output, "")
|
||||||
|
_, err = file.WriteString(cleanedOutput)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Can not write file:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 获取文件的绝对路径
|
||||||
|
absPath, err := filepath.Abs(filePath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Get file absPath failed:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
shorturl, err := utils.UploadText(absPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Upload failed, can not generate short URL.")
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
fmt.Println("Upload successful, short URL:", shorturl)
|
||||||
}
|
}
|
||||||
|
44
goecs.sh
44
goecs.sh
@@ -5,14 +5,21 @@
|
|||||||
# curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh
|
# curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh && chmod +x goecs.sh
|
||||||
|
|
||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
GGG OOO EEEE CCCC SSS
|
GGGGGGGG OOOOOOO EEEEEEEE CCCCCCCCC SSSSSSSSSS
|
||||||
G G O O E C S
|
GG GG OO OO EE CC SS
|
||||||
G O O EEE C SSS
|
GG OO OO EE CC SS
|
||||||
G GG O O E C S
|
GG OO OO EE CC SS
|
||||||
GGG OOO EEEE CCCC SSS
|
GG OO OO EEEEEEEE CC SSSSSSSSSS
|
||||||
|
GG GGGGGG OO OO EE CC SS
|
||||||
|
GG GG OO OO EE CC SS
|
||||||
|
GG GG OO OO EE CC SS
|
||||||
|
GGGGGGGG OOOOOOO EEEEEEEE CCCCCCCCC SSSSSSSSSS
|
||||||
EOF
|
EOF
|
||||||
cd /root >/dev/null 2>&1
|
|
||||||
|
|
||||||
|
cd /root >/dev/null 2>&1
|
||||||
|
if [ ! -d "/usr/bin/" ]; then
|
||||||
|
mkdir -p "/usr/bin/"
|
||||||
|
fi
|
||||||
_red() { echo -e "\033[31m\033[01m$@\033[0m"; }
|
_red() { echo -e "\033[31m\033[01m$@\033[0m"; }
|
||||||
_green() { echo -e "\033[32m\033[01m$@\033[0m"; }
|
_green() { echo -e "\033[32m\033[01m$@\033[0m"; }
|
||||||
_yellow() { echo -e "\033[33m\033[01m$@\033[0m"; }
|
_yellow() { echo -e "\033[33m\033[01m$@\033[0m"; }
|
||||||
@@ -115,7 +122,10 @@ goecs_check() {
|
|||||||
rm -rf README.md
|
rm -rf README.md
|
||||||
rm -rf LICENSE
|
rm -rf LICENSE
|
||||||
mv ecs goecs
|
mv ecs goecs
|
||||||
|
sleep 1
|
||||||
chmod 777 goecs
|
chmod 777 goecs
|
||||||
|
rm -rf /usr/bin/goecs
|
||||||
|
sleep 1
|
||||||
cp goecs /usr/bin/goecs
|
cp goecs /usr/bin/goecs
|
||||||
echo "goecs version:"
|
echo "goecs version:"
|
||||||
goecs -v || ./goecs -v
|
goecs -v || ./goecs -v
|
||||||
@@ -138,6 +148,7 @@ InstallSysbench() {
|
|||||||
Var_OSRelease="alpinelinux"
|
Var_OSRelease="alpinelinux"
|
||||||
elif [ -f "/etc/almalinux-release" ]; then # almalinux
|
elif [ -f "/etc/almalinux-release" ]; then # almalinux
|
||||||
Var_OSRelease="almalinux"
|
Var_OSRelease="almalinux"
|
||||||
|
# rockylinux
|
||||||
elif [ -f "/etc/arch-release" ]; then # archlinux
|
elif [ -f "/etc/arch-release" ]; then # archlinux
|
||||||
Var_OSRelease="arch"
|
Var_OSRelease="arch"
|
||||||
elif [ -f "/etc/freebsd-update.conf" ]; then # freebsd
|
elif [ -f "/etc/freebsd-update.conf" ]; then # freebsd
|
||||||
@@ -258,7 +269,7 @@ env_check() {
|
|||||||
unzip /tmp/sysbench.zip -d /tmp
|
unzip /tmp/sysbench.zip -d /tmp
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if ! commadn -v geekbench >/dev/null 2>&1; then
|
if ! command -v geekbench >/dev/null 2>&1; then
|
||||||
_green "Installing geekbench"
|
_green "Installing geekbench"
|
||||||
curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/cputest/main/dgb.sh" -o dgb.sh && chmod +x dgb.sh
|
curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/cputest/main/dgb.sh" -o dgb.sh && chmod +x dgb.sh
|
||||||
bash dgb.sh -v gb5
|
bash dgb.sh -v gb5
|
||||||
@@ -268,6 +279,17 @@ env_check() {
|
|||||||
_blue "to change version, or use"
|
_blue "to change version, or use"
|
||||||
echo "rm -rf /usr/bin/geekbench*"
|
echo "rm -rf /usr/bin/geekbench*"
|
||||||
_blue "to uninstall geekbench"
|
_blue "to uninstall geekbench"
|
||||||
|
rm -rf dgb.sh
|
||||||
|
fi
|
||||||
|
if ! command -v speedtest >/dev/null 2>&1; then
|
||||||
|
_green "Installing geekbench"
|
||||||
|
curl -L "${cdn_success_url}https://raw.githubusercontent.com/oneclickvirt/speedtest/main/dspt.sh" -o dspt.sh && chmod +x dspt.sh
|
||||||
|
bash dspt.sh
|
||||||
|
rm -rf dspt.sh
|
||||||
|
_blue "if you want to use golang origin speedtest, you can use"
|
||||||
|
echo "rm -rf /usr/bin/speedtest"
|
||||||
|
echo "rm -rf /usr/bin/speedtest-go"
|
||||||
|
_blue "to uninstall speedtest and speedtest-go"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,8 +297,9 @@ show_help() {
|
|||||||
cat <<"EOF"
|
cat <<"EOF"
|
||||||
Available commands:
|
Available commands:
|
||||||
|
|
||||||
env Check and install dd fio sysbench geekbench5
|
env Check and Install package: dd fio sysbench geekbench5 speedtest
|
||||||
install Install goecs command
|
install Install goecs command
|
||||||
|
upgrade Upgrade goecs command
|
||||||
help Show this message
|
help Show this message
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@@ -289,10 +312,7 @@ case "$1" in
|
|||||||
"env")
|
"env")
|
||||||
env_check
|
env_check
|
||||||
;;
|
;;
|
||||||
"install")
|
"install" | "upgrade")
|
||||||
goecs_check
|
|
||||||
;;
|
|
||||||
"upgrade")
|
|
||||||
goecs_check
|
goecs_check
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
main()
|
main()
|
||||||
|
@@ -1,542 +1,8 @@
|
|||||||
package network
|
package network1
|
||||||
|
|
||||||
import (
|
import "github.com/oneclickvirt/security/network"
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"runtime"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
"github.com/oneclickvirt/basics/model"
|
// 本包在main中不使用
|
||||||
"github.com/oneclickvirt/basics/network/baseinfo"
|
|
||||||
"github.com/oneclickvirt/basics/network/utils"
|
|
||||||
. "github.com/oneclickvirt/defaultset"
|
|
||||||
"github.com/oneclickvirt/security/network/printhead"
|
|
||||||
. "github.com/oneclickvirt/security/network/security"
|
|
||||||
)
|
|
||||||
|
|
||||||
// sortAndTranslateText 对原始文本进行排序和翻译
|
|
||||||
func sortAndTranslateText(orginList []string, language string, fields []string) string {
|
|
||||||
var result string
|
|
||||||
for _, key := range fields {
|
|
||||||
var displayKey string
|
|
||||||
if language == "zh" {
|
|
||||||
displayKey = model.TranslationMap[key]
|
|
||||||
if displayKey == "" {
|
|
||||||
displayKey = key
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayKey = key
|
|
||||||
}
|
|
||||||
for _, line := range orginList {
|
|
||||||
if strings.Contains(line, key) {
|
|
||||||
if displayKey == key {
|
|
||||||
result = result + line + "\n"
|
|
||||||
} else {
|
|
||||||
result = result + strings.ReplaceAll(line, key, displayKey) + "\n"
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetchAndLogInfo 子函数执行和日志记录
|
|
||||||
func fetchAndLogInfo(wg *sync.WaitGroup, ip string, scorePtr **model.SecurityScore, infoPtr **model.SecurityInfo, fetchFunc func(string) (*model.SecurityScore, *model.SecurityInfo, error)) {
|
|
||||||
defer wg.Done()
|
|
||||||
var err error
|
|
||||||
if scorePtr != nil && *scorePtr != nil && infoPtr != nil && *infoPtr != nil {
|
|
||||||
*scorePtr, *infoPtr, err = fetchFunc(ip)
|
|
||||||
} else if scorePtr == nil && infoPtr != nil && *infoPtr != nil {
|
|
||||||
_, *infoPtr, err = fetchFunc(ip)
|
|
||||||
} else if scorePtr != nil && *scorePtr != nil && infoPtr == nil {
|
|
||||||
*scorePtr, _, err = fetchFunc(ip)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
if model.EnableLoger {
|
|
||||||
Logger.Info(fmt.Sprintf("%s: %s", runtime.FuncForPC(reflect.ValueOf(fetchFunc).Pointer()).Name(), err.Error()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ipv4SecurityCheck 检测 ipv4 安全信息和安全得分
|
|
||||||
func Ipv4SecurityCheck(ipInfo *model.IpInfo, cheervisionInfo *model.SecurityInfo, language string) (string, error) {
|
|
||||||
if model.EnableLoger {
|
|
||||||
InitLogger()
|
|
||||||
defer Logger.Sync()
|
|
||||||
}
|
|
||||||
if ipInfo == nil {
|
|
||||||
if model.EnableLoger {
|
|
||||||
Logger.Info("ipv4 is not available")
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("ipv4 is not available")
|
|
||||||
}
|
|
||||||
if cheervisionInfo == nil {
|
|
||||||
if model.EnableLoger {
|
|
||||||
Logger.Info("ipv4 cheervisionInfo nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
ip, temp, orgin, result string
|
|
||||||
wg sync.WaitGroup
|
|
||||||
iPInfoIoInfo = &model.SecurityInfo{}
|
|
||||||
scamalyticsInfo = &model.SecurityInfo{}
|
|
||||||
abuseipdbInfo = &model.SecurityInfo{}
|
|
||||||
ip2locationIoInfo = &model.SecurityInfo{}
|
|
||||||
ipapicomInfo = &model.SecurityInfo{}
|
|
||||||
ipwhoisioInfo = &model.SecurityInfo{}
|
|
||||||
ipregistryCoInfo = &model.SecurityInfo{}
|
|
||||||
ipdataCoInfo = &model.SecurityInfo{}
|
|
||||||
dbIpComInfo = &model.SecurityInfo{}
|
|
||||||
ipapiisInfo = &model.SecurityInfo{}
|
|
||||||
ipapiComInfo = &model.SecurityInfo{}
|
|
||||||
abstractapiInfo = &model.SecurityInfo{}
|
|
||||||
ipqualityscoreComInfo = &model.SecurityInfo{}
|
|
||||||
|
|
||||||
scamalyticsScore = &model.SecurityScore{}
|
|
||||||
virustotalScore = &model.SecurityScore{}
|
|
||||||
abuseipdbScore = &model.SecurityScore{}
|
|
||||||
dbIpComScore = &model.SecurityScore{}
|
|
||||||
ipapiisScore = &model.SecurityScore{}
|
|
||||||
ipdataCoScore = &model.SecurityScore{}
|
|
||||||
ipapiComScore = &model.SecurityScore{}
|
|
||||||
ipqualityscoreComScore = &model.SecurityScore{}
|
|
||||||
)
|
|
||||||
ip = ipInfo.Ip
|
|
||||||
wg.Add(14)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &iPInfoIoInfo, IPInfoIo)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &scamalyticsScore, &scamalyticsInfo, Scamalytics)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &virustotalScore, nil, Virustotal)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &abuseipdbScore, &abuseipdbInfo, Abuseipdb)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &ip2locationIoInfo, Ip2locationIo)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &ipapicomInfo, IpApiCom)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &ipwhoisioInfo, IpwhoisIo)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &ipregistryCoInfo, IpregistryCo)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipdataCoScore, &ipdataCoInfo, IpdataCo)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &dbIpComScore, &dbIpComInfo, DbIpCom)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipapiisScore, &ipapiisInfo, Ipapiis)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipapiComScore, &ipapiComInfo, IpapiCom)
|
|
||||||
go fetchAndLogInfo(&wg, ip, nil, &abstractapiInfo, Abstractapi)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipqualityscoreComScore, &ipqualityscoreComInfo, IpqualityscoreCom)
|
|
||||||
wg.Wait()
|
|
||||||
// 构建非空信息
|
|
||||||
var allScoreList []model.SecurityScore
|
|
||||||
scorePointers := []*model.SecurityScore{virustotalScore, scamalyticsScore, abuseipdbScore, dbIpComScore,
|
|
||||||
ipapiisScore, ipapiComScore, ipdataCoScore, ipqualityscoreComScore}
|
|
||||||
for _, score := range scorePointers {
|
|
||||||
if score != nil {
|
|
||||||
allScoreList = append(allScoreList, *score)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var allInfoList []model.SecurityInfo
|
|
||||||
infoPointers := []*model.SecurityInfo{iPInfoIoInfo, scamalyticsInfo, abuseipdbInfo, ip2locationIoInfo, ipapicomInfo,
|
|
||||||
ipwhoisioInfo, ipregistryCoInfo, ipdataCoInfo, dbIpComInfo, ipapiisInfo, ipapiComInfo, abstractapiInfo,
|
|
||||||
cheervisionInfo, ipqualityscoreComInfo}
|
|
||||||
for _, info := range infoPointers {
|
|
||||||
if info != nil {
|
|
||||||
allInfoList = append(allInfoList, *info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 构建回传的文本内容
|
|
||||||
temp += FormatSecurityScore(allScoreList)
|
|
||||||
temp += "\n"
|
|
||||||
temp += FormatSecurityInfo(allInfoList)
|
|
||||||
// 分割输入为行
|
|
||||||
lines := strings.Split(temp, "\n")
|
|
||||||
// 初始化一个映射用于存储冒号之前的内容及其对应的行数
|
|
||||||
contentMap := make(map[string][]int)
|
|
||||||
// 遍历每一行,提取冒号之前的内容及其行数
|
|
||||||
for i, line := range lines {
|
|
||||||
// 如果行为空则跳过
|
|
||||||
if line == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 切割行,以冒号为分隔符
|
|
||||||
parts := strings.Split(line, ":")
|
|
||||||
// 获取冒号之前的内容
|
|
||||||
content := parts[0]
|
|
||||||
// 将当前行的行号添加到映射中
|
|
||||||
contentMap[content] = append(contentMap[content], i)
|
|
||||||
}
|
|
||||||
// 遍历映射,拼接相同内容的行
|
|
||||||
for _, lineNumbers := range contentMap {
|
|
||||||
if len(lineNumbers) > 1 { // 只对有多个行的内容进行拼接
|
|
||||||
// 初始化一个字符串切片,用于存储拼接后的行
|
|
||||||
var mergedLines []string
|
|
||||||
// 遍历相同内容的行 添加当前行到拼接后的行中
|
|
||||||
for _, lineNumber := range lineNumbers {
|
|
||||||
if lineNumber == lineNumbers[0] {
|
|
||||||
mergedLines = append(mergedLines, strings.TrimSpace(lines[lineNumber]))
|
|
||||||
} else {
|
|
||||||
mergedLines = append(mergedLines, strings.TrimSpace(strings.Split(lines[lineNumber], ":")[1]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 将拼接后的行以空格连接起来
|
|
||||||
mergedLine := strings.Join(mergedLines, " ")
|
|
||||||
// 替换原始行中相同内容的行为拼接后的行,仅替换一次,其他行标注要删除
|
|
||||||
isMerged := false
|
|
||||||
for _, lineNumber := range lineNumbers {
|
|
||||||
if !isMerged {
|
|
||||||
lines[lineNumber] = mergedLine
|
|
||||||
isMerged = true
|
|
||||||
} else {
|
|
||||||
lines[lineNumber] += "delete"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 删除对应的行,构建原始文本
|
|
||||||
for _, line := range lines {
|
|
||||||
if !strings.Contains(line, "delete") {
|
|
||||||
orgin = orgin + line + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orginList := strings.Split(orgin, "\n")
|
|
||||||
// 将原始文本按要求进行排序和翻译
|
|
||||||
var score model.SecurityScore
|
|
||||||
scoreFields := utils.ExtractFieldNames(&score)
|
|
||||||
var info model.SecurityInfo
|
|
||||||
infoFields := utils.ExtractFieldNames(&info)
|
|
||||||
// 拼接安全得分
|
|
||||||
if language == "zh" {
|
|
||||||
result += Blue("安全得分:") + "\n"
|
|
||||||
} else if language == "en" {
|
|
||||||
result = Blue("Security Score:") + "\n"
|
|
||||||
}
|
|
||||||
if len(scoreFields) > 4 {
|
|
||||||
result += sortAndTranslateText(orginList, language, scoreFields[:len(scoreFields)-4])
|
|
||||||
} else {
|
|
||||||
result += sortAndTranslateText(orginList, language, scoreFields)
|
|
||||||
}
|
|
||||||
// 安全信息中前三个是字符串类型的得分
|
|
||||||
result += sortAndTranslateText(orginList, language, infoFields[:3])
|
|
||||||
// 需要确保后4个属性都为对应属性时才进行说明的拼接
|
|
||||||
if len(scoreFields) > 4 {
|
|
||||||
t := ""
|
|
||||||
foundKeys := 0
|
|
||||||
for _, key := range scoreFields[len(scoreFields)-4:] {
|
|
||||||
var displayKey string
|
|
||||||
if language == "zh" {
|
|
||||||
displayKey = model.TranslationMap[key]
|
|
||||||
if displayKey == "" {
|
|
||||||
displayKey = key
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
displayKey = key
|
|
||||||
}
|
|
||||||
found := false
|
|
||||||
for _, line := range orginList {
|
|
||||||
if strings.Contains(line, key) {
|
|
||||||
key = strings.ReplaceAll(key, ": ", "")
|
|
||||||
if displayKey == key {
|
|
||||||
t = t + line + " "
|
|
||||||
} else {
|
|
||||||
t = t + strings.ReplaceAll(line, key, displayKey) + " "
|
|
||||||
}
|
|
||||||
found = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if found {
|
|
||||||
foundKeys++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if foundKeys == 4 {
|
|
||||||
if language == "zh" {
|
|
||||||
result = result + "黑名单记录统计:(有多少黑名单网站有记录):\n" + t + "\n"
|
|
||||||
} else if language == "en" {
|
|
||||||
result = result + "Blacklist_Records_Statistics(how many blacklisted websites have records):\n" + t + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 拼接安全信息
|
|
||||||
if language == "zh" {
|
|
||||||
result += Blue("安全信息:") + "\n"
|
|
||||||
} else if language == "en" {
|
|
||||||
result += Blue("Security Info:") + "\n"
|
|
||||||
}
|
|
||||||
result += sortAndTranslateText(orginList, language, infoFields[3:])
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ipv6SecurityCheck 检测 ipv4 安全信息和安全得分
|
|
||||||
func Ipv6SecurityCheck(ipInfo *model.IpInfo, cheervisionInfo *model.SecurityInfo, language string) (string, error) {
|
|
||||||
if model.EnableLoger {
|
|
||||||
InitLogger()
|
|
||||||
defer Logger.Sync()
|
|
||||||
}
|
|
||||||
if ipInfo == nil {
|
|
||||||
if model.EnableLoger {
|
|
||||||
Logger.Info("ipv6 is not available")
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("ipv6 is not available")
|
|
||||||
}
|
|
||||||
if cheervisionInfo == nil {
|
|
||||||
if model.EnableLoger {
|
|
||||||
Logger.Info("ipv6 cheervisionInfo nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var (
|
|
||||||
ip, temp, orgin, result string
|
|
||||||
wg sync.WaitGroup
|
|
||||||
scamalyticsInfo = &model.SecurityInfo{}
|
|
||||||
abuseipdbInfo = &model.SecurityInfo{}
|
|
||||||
ipapiisInfo = &model.SecurityInfo{}
|
|
||||||
ipapiComInfo = &model.SecurityInfo{}
|
|
||||||
scamalyticsScore = &model.SecurityScore{}
|
|
||||||
abuseipdbScore = &model.SecurityScore{}
|
|
||||||
ipapiisScore = &model.SecurityScore{}
|
|
||||||
ipapiComScore = &model.SecurityScore{}
|
|
||||||
)
|
|
||||||
ip = ipInfo.Ip
|
|
||||||
wg.Add(4)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &scamalyticsScore, &scamalyticsInfo, Scamalytics)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &abuseipdbScore, &abuseipdbInfo, Abuseipdb)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipapiisScore, &ipapiisInfo, Ipapiis)
|
|
||||||
go fetchAndLogInfo(&wg, ip, &ipapiComScore, &ipapiComInfo, IpapiComIpv6)
|
|
||||||
wg.Wait()
|
|
||||||
// 构建非空信息
|
|
||||||
var allScoreList []model.SecurityScore
|
|
||||||
scorePointers := []*model.SecurityScore{scamalyticsScore, abuseipdbScore, ipapiisScore, ipapiComScore}
|
|
||||||
for _, score := range scorePointers {
|
|
||||||
if score != nil {
|
|
||||||
allScoreList = append(allScoreList, *score)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var allInfoList []model.SecurityInfo
|
|
||||||
infoPointers := []*model.SecurityInfo{scamalyticsInfo, abuseipdbInfo, ipapiisInfo, ipapiComInfo, cheervisionInfo}
|
|
||||||
for _, info := range infoPointers {
|
|
||||||
if info != nil {
|
|
||||||
allInfoList = append(allInfoList, *info)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 构建回传的文本内容
|
|
||||||
temp += FormatSecurityScore(allScoreList)
|
|
||||||
temp += "\n"
|
|
||||||
temp += FormatSecurityInfo(allInfoList)
|
|
||||||
// 分割输入为行
|
|
||||||
lines := strings.Split(temp, "\n")
|
|
||||||
// 初始化一个映射用于存储冒号之前的内容及其对应的行数
|
|
||||||
contentMap := make(map[string][]int)
|
|
||||||
// 遍历每一行,提取冒号之前的内容及其行数
|
|
||||||
for i, line := range lines {
|
|
||||||
// 如果行为空则跳过
|
|
||||||
if line == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// 切割行,以冒号为分隔符
|
|
||||||
parts := strings.Split(line, ":")
|
|
||||||
// 获取冒号之前的内容
|
|
||||||
content := parts[0]
|
|
||||||
// 将当前行的行号添加到映射中
|
|
||||||
contentMap[content] = append(contentMap[content], i)
|
|
||||||
}
|
|
||||||
// 遍历映射,拼接相同内容的行
|
|
||||||
for _, lineNumbers := range contentMap {
|
|
||||||
if len(lineNumbers) > 1 { // 只对有多个行的内容进行拼接
|
|
||||||
// 初始化一个字符串切片,用于存储拼接后的行
|
|
||||||
var mergedLines []string
|
|
||||||
// 遍历相同内容的行 添加当前行到拼接后的行中
|
|
||||||
for _, lineNumber := range lineNumbers {
|
|
||||||
if lineNumber == lineNumbers[0] {
|
|
||||||
mergedLines = append(mergedLines, strings.TrimSpace(lines[lineNumber]))
|
|
||||||
} else {
|
|
||||||
mergedLines = append(mergedLines, strings.TrimSpace(strings.Split(lines[lineNumber], ":")[1]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 将拼接后的行以空格连接起来
|
|
||||||
mergedLine := strings.Join(mergedLines, " ")
|
|
||||||
// 替换原始行中相同内容的行为拼接后的行,仅替换一次,其他行标注要删除
|
|
||||||
isMerged := false
|
|
||||||
for _, lineNumber := range lineNumbers {
|
|
||||||
if !isMerged {
|
|
||||||
lines[lineNumber] = mergedLine
|
|
||||||
isMerged = true
|
|
||||||
} else {
|
|
||||||
lines[lineNumber] += "delete"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 删除对应的行,构建原始文本
|
|
||||||
for _, line := range lines {
|
|
||||||
if !strings.Contains(line, "delete") {
|
|
||||||
orgin = orgin + line + "\n"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
orginList := strings.Split(orgin, "\n")
|
|
||||||
var score model.SecurityScore
|
|
||||||
scoreFields := utils.ExtractFieldNames(&score)
|
|
||||||
var info model.SecurityInfo
|
|
||||||
infoFields := utils.ExtractFieldNames(&info)
|
|
||||||
// 拼接安全得分
|
|
||||||
if language == "zh" {
|
|
||||||
result += Blue("安全得分:") + "\n"
|
|
||||||
} else if language == "en" {
|
|
||||||
result = Blue("Security Score:") + "\n"
|
|
||||||
}
|
|
||||||
result += sortAndTranslateText(orginList, language, scoreFields)
|
|
||||||
result += sortAndTranslateText(orginList, language, infoFields[:3])
|
|
||||||
// 拼接完整安全信息
|
|
||||||
if language == "zh" {
|
|
||||||
result += Blue("安全信息:") + "\n"
|
|
||||||
} else if language == "en" {
|
|
||||||
result += Blue("Security Info:") + "\n"
|
|
||||||
}
|
|
||||||
result += sortAndTranslateText(orginList, language, infoFields[3:])
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// processPrintIPInfo 处理IP信息
|
|
||||||
func processPrintIPInfo(headASNString string, headLocationString string, ipResult *model.IpInfo) string {
|
|
||||||
var info string
|
|
||||||
// 处理ASN信息
|
|
||||||
if ipResult.ASN != "" || ipResult.Org != "" {
|
|
||||||
info += headASNString
|
|
||||||
if ipResult.ASN != "" {
|
|
||||||
info += "AS" + ipResult.ASN
|
|
||||||
if ipResult.Org != "" {
|
|
||||||
info += " "
|
|
||||||
}
|
|
||||||
}
|
|
||||||
info += ipResult.Org + "\n"
|
|
||||||
}
|
|
||||||
// 处理位置信息
|
|
||||||
if ipResult.City != "" || ipResult.Region != "" || ipResult.Country != "" {
|
|
||||||
info += headLocationString
|
|
||||||
if ipResult.City != "" {
|
|
||||||
info += ipResult.City + " / "
|
|
||||||
}
|
|
||||||
if ipResult.Region != "" {
|
|
||||||
info += ipResult.Region + " / "
|
|
||||||
}
|
|
||||||
if ipResult.Country != "" {
|
|
||||||
info += ipResult.Country
|
|
||||||
}
|
|
||||||
info += "\n"
|
|
||||||
}
|
|
||||||
return info
|
|
||||||
}
|
|
||||||
|
|
||||||
// NetworkCheck 查询网络信息
|
|
||||||
// checkType 可选 both ipv4 ipv6
|
|
||||||
// enableSecurityCheck 可选 true false
|
|
||||||
// language 暂时仅支持 en 或 zh
|
|
||||||
// 回传 ipInfo securityInfo err
|
|
||||||
func NetworkCheck(checkType string, enableSecurityCheck bool, language string) (string, string, error) {
|
func NetworkCheck(checkType string, enableSecurityCheck bool, language string) (string, string, error) {
|
||||||
var ipInfo, securityInfo string
|
return network.NetworkCheck(checkType, enableSecurityCheck, language)
|
||||||
if checkType == "both" {
|
|
||||||
ipInfoV4Result, cheervisionInfoV4, ipInfoV6Result, cheervisionInfoV6, _ := baseinfo.RunIpCheck("both")
|
|
||||||
if ipInfoV4Result != nil {
|
|
||||||
ipInfo += processPrintIPInfo(" IPV4 ASN : ", " IPV4 Location : ", ipInfoV4Result)
|
|
||||||
}
|
|
||||||
if ipInfoV6Result != nil {
|
|
||||||
ipInfo += processPrintIPInfo(" IPV6 ASN : ", " IPV6 Location : ", ipInfoV6Result)
|
|
||||||
}
|
|
||||||
// 检测是否需要查询相关安全信息
|
|
||||||
if enableSecurityCheck {
|
|
||||||
var (
|
|
||||||
wg sync.WaitGroup
|
|
||||||
ipv4Res, ipv6Res, ipv4DNSRes, ipv6DNSRes string
|
|
||||||
err1, err2 error
|
|
||||||
)
|
|
||||||
wg.Add(4)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv4DNSRes = BlackList(ipInfoV4Result, "ipv4", language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv6DNSRes = BlackList(ipInfoV6Result, "ipv6", language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv4Res, err1 = Ipv4SecurityCheck(ipInfoV4Result, cheervisionInfoV4, language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv6Res, err2 = Ipv6SecurityCheck(ipInfoV6Result, cheervisionInfoV6, language)
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
securityHead, err3 := printhead.PrintDatabaseInfo(language)
|
|
||||||
if err1 == nil && err2 == nil && err3 == nil {
|
|
||||||
securityInfo = securityHead + Green("IPV4:") + "\n" + ipv4Res + ipv4DNSRes + Green("IPV6:") + "\n" + ipv6Res + ipv6DNSRes
|
|
||||||
return ipInfo, securityInfo, nil
|
|
||||||
} else if err1 == nil && err2 != nil && err3 == nil {
|
|
||||||
securityInfo = securityHead + Green("IPV4:") + "\n" + ipv4Res + ipv4DNSRes
|
|
||||||
return ipInfo, securityInfo, nil
|
|
||||||
} else if err1 != nil && err2 == nil && err3 == nil {
|
|
||||||
securityInfo = securityHead + Green("IPV6:") + "\n" + ipv6Res + ipv6DNSRes
|
|
||||||
return ipInfo, securityInfo, nil
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
} else if checkType == "ipv4" {
|
|
||||||
ipInfoV4Result, cheervisionInfoV4, _, _, _ := baseinfo.RunIpCheck("ipv4")
|
|
||||||
if ipInfoV4Result != nil {
|
|
||||||
ipInfo += processPrintIPInfo(" IPV4 ASN : ", " IPV4 Location : ", ipInfoV4Result)
|
|
||||||
}
|
|
||||||
if enableSecurityCheck {
|
|
||||||
var (
|
|
||||||
wg sync.WaitGroup
|
|
||||||
ipv4Res, ipv4DNSRes string
|
|
||||||
err1 error
|
|
||||||
)
|
|
||||||
wg.Add(2)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv4DNSRes = BlackList(ipInfoV4Result, "ipv4", language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv4Res, err1 = Ipv4SecurityCheck(ipInfoV4Result, cheervisionInfoV4, language)
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
securityHead, err2 := printhead.PrintDatabaseInfo(language)
|
|
||||||
if err1 == nil && err2 == nil {
|
|
||||||
securityInfo = securityHead + Green("IPV4:") + "\n" + ipv4Res + ipv4DNSRes
|
|
||||||
return ipInfo, securityInfo, nil
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
} else if checkType == "ipv6" {
|
|
||||||
_, _, ipInfoV6Result, cheervisionInfoV6, _ := baseinfo.RunIpCheck("ipv6")
|
|
||||||
if ipInfoV6Result != nil {
|
|
||||||
ipInfo += processPrintIPInfo(" IPV6 ASN : ", " IPV6 Location : ", ipInfoV6Result)
|
|
||||||
}
|
|
||||||
if enableSecurityCheck {
|
|
||||||
var (
|
|
||||||
wg sync.WaitGroup
|
|
||||||
ipv6Res, ipv6DNSRes string
|
|
||||||
err1 error
|
|
||||||
)
|
|
||||||
wg.Add(2)
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv6DNSRes = BlackList(ipInfoV6Result, "ipv6", language)
|
|
||||||
}()
|
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
|
||||||
ipv6Res, err1 = Ipv6SecurityCheck(ipInfoV6Result, cheervisionInfoV6, language)
|
|
||||||
}()
|
|
||||||
wg.Wait()
|
|
||||||
securityHead, err2 := printhead.PrintDatabaseInfo(language)
|
|
||||||
if err1 == nil && err2 == nil {
|
|
||||||
securityInfo = securityHead + Green("IPV6:") + "\n" + ipv6Res + ipv6DNSRes
|
|
||||||
return ipInfo, securityInfo, nil
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return ipInfo, "", nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", "", fmt.Errorf("wrong in NetworkCheck")
|
|
||||||
}
|
}
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
package network
|
package network1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// 常用端口阻断检测 TCP/UDP/ICMP 协议
|
// 常用端口阻断检测 TCP/UDP/ICMP 协议
|
||||||
|
// 本包不在main中使用
|
||||||
func EmailCheck() {
|
func EmailCheck() {
|
||||||
res := email.EmailCheck()
|
res := email.EmailCheck()
|
||||||
fmt.Println(res)
|
fmt.Println(res)
|
||||||
|
@@ -3,6 +3,7 @@ package speedtest
|
|||||||
import (
|
import (
|
||||||
"github.com/oneclickvirt/speedtest/model"
|
"github.com/oneclickvirt/speedtest/model"
|
||||||
"github.com/oneclickvirt/speedtest/sp"
|
"github.com/oneclickvirt/speedtest/sp"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,7 +12,11 @@ func ShowHead(language string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NearbySP() {
|
func NearbySP() {
|
||||||
|
if runtime.GOOS == "windows" || sp.OfficialAvailableTest() != nil {
|
||||||
sp.NearbySpeedTest()
|
sp.NearbySpeedTest()
|
||||||
|
} else {
|
||||||
|
sp.OfficialNearbySpeedTest()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func CustomSP(platform, operator string, num int) {
|
func CustomSP(platform, operator string, num int) {
|
||||||
@@ -53,5 +58,9 @@ func CustomSP(platform, operator string, num int) {
|
|||||||
}
|
}
|
||||||
parseType = "id"
|
parseType = "id"
|
||||||
}
|
}
|
||||||
|
if runtime.GOOS == "windows" || sp.OfficialAvailableTest() != nil {
|
||||||
sp.CustomSpeedTest(url, parseType, num)
|
sp.CustomSpeedTest(url, parseType, num)
|
||||||
|
} else {
|
||||||
|
sp.OfficialCustomSpeedTest(url, parseType, num)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
175
utils/utils.go
Normal file
175
utils/utils.go
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"github.com/imroc/req/v3"
|
||||||
|
"github.com/oneclickvirt/UnlockTests/uts"
|
||||||
|
"github.com/oneclickvirt/basics/system"
|
||||||
|
"github.com/oneclickvirt/security/network"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"unicode/utf8"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrintCenteredTitle 根据指定的宽度打印居中标题
|
||||||
|
func PrintCenteredTitle(title string, width int) {
|
||||||
|
// 计算字符串的字符数
|
||||||
|
titleLength := utf8.RuneCountInString(title)
|
||||||
|
totalPadding := width - titleLength
|
||||||
|
padding := totalPadding / 2
|
||||||
|
paddingStr := strings.Repeat("-", padding)
|
||||||
|
fmt.Println(paddingStr + title + paddingStr + strings.Repeat("-", totalPadding%2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintHead 根据语言打印头部信息
|
||||||
|
func PrintHead(language string, width int, ecsVersion string) {
|
||||||
|
if language == "zh" {
|
||||||
|
PrintCenteredTitle("融合怪测试", width)
|
||||||
|
fmt.Printf("版本:%s\n", ecsVersion)
|
||||||
|
fmt.Println("测评频道: https://t.me/vps_reviews\n" +
|
||||||
|
"Go项目地址:https://github.com/oneclickvirt/ecs\n" +
|
||||||
|
"Shell项目地址:https://github.com/spiritLHLS/ecs")
|
||||||
|
} else {
|
||||||
|
PrintCenteredTitle("Fusion Monster Test", width)
|
||||||
|
fmt.Printf("Version: %s\n", ecsVersion)
|
||||||
|
fmt.Println("Review Channel: https://t.me/vps_reviews\n" +
|
||||||
|
"Go Project URL: https://github.com/oneclickvirt/ecs\n" +
|
||||||
|
"Shell Project URL: https://github.com/spiritLHLS/ecs")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityCheck 执行安全检查
|
||||||
|
func SecurityCheck(language, nt3CheckType string) (string, string, string) {
|
||||||
|
var wgt sync.WaitGroup
|
||||||
|
var ipInfo, securityInfo, systemInfo string
|
||||||
|
var err error
|
||||||
|
wgt.Add(2)
|
||||||
|
go func() {
|
||||||
|
defer wgt.Done()
|
||||||
|
ipInfo, securityInfo, err = network.NetworkCheck("both", true, language)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
defer wgt.Done()
|
||||||
|
systemInfo = system.CheckSystemInfo(language)
|
||||||
|
}()
|
||||||
|
wgt.Wait()
|
||||||
|
basicInfo := systemInfo + ipInfo
|
||||||
|
if strings.Contains(ipInfo, "IPV4") && strings.Contains(ipInfo, "IPV6") {
|
||||||
|
uts.IPV4 = true
|
||||||
|
uts.IPV6 = true
|
||||||
|
if nt3CheckType == "" {
|
||||||
|
nt3CheckType = "ipv4"
|
||||||
|
}
|
||||||
|
} else if strings.Contains(ipInfo, "IPV4") {
|
||||||
|
uts.IPV4 = true
|
||||||
|
uts.IPV6 = false
|
||||||
|
if nt3CheckType == "" {
|
||||||
|
nt3CheckType = "ipv4"
|
||||||
|
}
|
||||||
|
} else if strings.Contains(ipInfo, "IPV6") {
|
||||||
|
uts.IPV6 = true
|
||||||
|
uts.IPV4 = false
|
||||||
|
if nt3CheckType == "" {
|
||||||
|
nt3CheckType = "ipv6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if nt3CheckType == "ipv4" && !strings.Contains(ipInfo, "IPV4") && strings.Contains(ipInfo, "IPV6") {
|
||||||
|
nt3CheckType = "ipv6"
|
||||||
|
} else if nt3CheckType == "ipv6" && !strings.Contains(ipInfo, "IPV6") && strings.Contains(ipInfo, "IPV4") {
|
||||||
|
nt3CheckType = "ipv4"
|
||||||
|
}
|
||||||
|
basicInfo = strings.ReplaceAll(basicInfo, "\n\n", "\n")
|
||||||
|
return basicInfo, securityInfo, nt3CheckType
|
||||||
|
}
|
||||||
|
|
||||||
|
// CaptureOutput 捕获函数输出和错误输出并返回字符串
|
||||||
|
func CaptureOutput(f func()) string {
|
||||||
|
// 保存旧的 stdout 和 stderr
|
||||||
|
oldStdout := os.Stdout
|
||||||
|
oldStderr := os.Stderr
|
||||||
|
// 创建管道
|
||||||
|
stdoutPipeR, stdoutPipeW, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
return "Error creating stdout pipe"
|
||||||
|
}
|
||||||
|
stderrPipeR, stderrPipeW, err := os.Pipe()
|
||||||
|
if err != nil {
|
||||||
|
stdoutPipeW.Close()
|
||||||
|
stdoutPipeR.Close()
|
||||||
|
return "Error creating stderr pipe"
|
||||||
|
}
|
||||||
|
// 替换标准输出和标准错误输出为管道写入端
|
||||||
|
os.Stdout = stdoutPipeW
|
||||||
|
os.Stderr = stderrPipeW
|
||||||
|
// 恢复标准输出和标准错误输出
|
||||||
|
defer func() {
|
||||||
|
os.Stdout = oldStdout
|
||||||
|
os.Stderr = oldStderr
|
||||||
|
stdoutPipeW.Close()
|
||||||
|
stderrPipeW.Close()
|
||||||
|
stdoutPipeR.Close()
|
||||||
|
stderrPipeR.Close()
|
||||||
|
}()
|
||||||
|
// 缓冲区
|
||||||
|
var stdoutBuf, stderrBuf bytes.Buffer
|
||||||
|
// 并发读取 stdout 和 stderr
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
multiWriter := io.MultiWriter(&stdoutBuf, oldStdout)
|
||||||
|
io.Copy(multiWriter, stdoutPipeR)
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
multiWriter := io.MultiWriter(&stderrBuf, oldStderr)
|
||||||
|
io.Copy(multiWriter, stderrPipeR)
|
||||||
|
done <- struct{}{}
|
||||||
|
}()
|
||||||
|
// 执行函数
|
||||||
|
f()
|
||||||
|
// 关闭管道写入端,让管道读取端可以读取所有数据
|
||||||
|
stdoutPipeW.Close()
|
||||||
|
stderrPipeW.Close()
|
||||||
|
// 等待两个 goroutine 完成
|
||||||
|
<-done
|
||||||
|
<-done
|
||||||
|
// 返回捕获的输出字符串
|
||||||
|
return stdoutBuf.String() + stderrBuf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrintAndCapture 捕获函数输出的同时打印内容
|
||||||
|
func PrintAndCapture(f func(), tempOutput, output string) string {
|
||||||
|
tempOutput = CaptureOutput(f)
|
||||||
|
output += tempOutput
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadText 上传文本内容到指定URL
|
||||||
|
func UploadText(absPath string) (string, error) {
|
||||||
|
url := "https://paste.spiritlhl.net/api/upload"
|
||||||
|
token := network.SecurityUploadToken
|
||||||
|
client := req.DefaultClient()
|
||||||
|
file, _ := os.Open(absPath)
|
||||||
|
resp, err := client.R().
|
||||||
|
SetHeader("Authorization", token).
|
||||||
|
SetHeader("Format", "RANDOM").
|
||||||
|
SetHeader("Max-Views", "0").
|
||||||
|
SetHeader("UploadText", "true").
|
||||||
|
SetHeader("Content-Type", "multipart/form-data").
|
||||||
|
SetHeader("No-JSON", "true").
|
||||||
|
SetFileReader("file", "goecs.txt", file).
|
||||||
|
Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if resp.StatusCode >= 200 && resp.StatusCode <= 299 {
|
||||||
|
return resp.String(), nil
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("upload failed with status code: %d", resp.StatusCode)
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user