star/tcping/cmd.go
2024-03-11 22:50:09 +08:00

175 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tcping
import (
"fmt"
"github.com/spf13/cobra"
"os"
"os/signal"
"strconv"
"syscall"
"time"
)
var (
counter int
timeout string
interval string
sigs chan os.Signal
httpMode bool
httpHead bool
httpPost bool
httpUA string
permanent bool
dnsServer []string
)
var Cmd = &cobra.Command{
Use: "tcping",
Short: "tcp/http ping 工具",
Long: "使用进行Tcp或Http协议进行ping探测",
Example: `
1. dns over tcp
> tcping google.com
2. dns over tcp with custom port
> tcping google.com 443
3. dns over http
> tcping -H google.com
4. dns with URI schema
> tcping http://hui.lu
`,
Run: func(cmd *cobra.Command, args []string) {
sigs = make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
if permanent && counter != 4 {
fmt.Println("不能同时指定-t与-c请检查您的输入")
return
}
if permanent {
counter = 0
}
if len(args) != 2 && len(args) != 1 {
cmd.Usage()
return
}
host := args[0]
var (
err error
port int
schema string
)
if len(args) == 2 {
port, err = strconv.Atoi(args[1])
if err != nil {
fmt.Println("端口应当为Int类型")
cmd.Usage()
return
}
schema = TCP.String()
} else {
var matched bool
schema, host, port, matched = CheckURI(host)
if !matched {
fmt.Println("不是一个合法的URI")
cmd.Usage()
return
}
}
var timeoutDuration time.Duration
if res, err := strconv.Atoi(timeout); err == nil {
timeoutDuration = time.Duration(res) * time.Millisecond
} else {
timeoutDuration, err = time.ParseDuration(timeout)
if err != nil {
fmt.Println("parse timeout failed", err)
cmd.Usage()
return
}
}
var intervalDuration time.Duration
if res, err := strconv.Atoi(interval); err == nil {
intervalDuration = time.Duration(res) * time.Millisecond
} else {
intervalDuration, err = time.ParseDuration(interval)
if err != nil {
fmt.Println("parse interval failed", err)
cmd.Usage()
return
}
}
var protocol Protocol
if httpMode {
protocol = HTTP
} else {
protocol, err = NewProtocol(schema)
if err != nil {
fmt.Println(err)
cmd.Usage()
return
}
}
if len(dnsServer) != 0 {
UseCustomeDNS(dnsServer)
}
parseHost := FormatIP(host)
target := Target{
Timeout: timeoutDuration,
Interval: intervalDuration,
Host: parseHost,
Port: port,
Counter: counter,
Protocol: protocol,
}
var pinger Pinger
switch protocol {
case TCP:
pinger = NewTCPing()
case HTTP, HTTPS:
var httpMethod string
switch {
case httpHead:
httpMethod = "HEAD"
case httpPost:
httpMethod = "POST"
default:
httpMethod = "GET"
}
pinger = NewHTTPing(httpMethod)
default:
fmt.Printf("schema: %s not support\n", schema)
cmd.Usage()
return
}
pinger.SetTarget(&target)
pingerDone := pinger.Start()
select {
case <-pingerDone:
break
case <-sigs:
break
}
fmt.Println(pinger.Result())
},
}
func init() {
Cmd.Flags().IntVarP(&counter, "counter", "c", 4, "ping的次数")
Cmd.Flags().BoolVarP(&permanent, "permanent", "t", false, "一直ping下去")
Cmd.Flags().StringVarP(&timeout, "timeout", "T", "1s", `超时时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
Cmd.Flags().StringVarP(&interval, "interval", "I", "1s", `ping间隔时间, 单位为 "ns", "us" (or "µs"), "ms", "s", "m", "h"`)
Cmd.Flags().BoolVarP(&httpMode, "http", "H", false, `Use "HTTP" mode. will ignore URI Schema, force to http`)
Cmd.Flags().BoolVar(&httpHead, "head", false, `使用http head模式`)
Cmd.Flags().BoolVar(&httpPost, "post", false, `使用http post模式`)
Cmd.Flags().StringVar(&httpUA, "user-agent", "victorique/tcping", `自定义UA`)
Cmd.Flags().StringArrayVarP(&dnsServer, "dns-server", "D", nil, `使用自定义DNS服务器`)
}