You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
star/tcping/cmd.go

175 lines
3.8 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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服务器`)
}