From eb9f7b8031b1f07a7c255a7eeb5530b482766eb7 Mon Sep 17 00:00:00 2001 From: ren yuze Date: Wed, 4 Sep 2019 16:06:52 +0800 Subject: [PATCH] init --- main.go | 5 + vtqe/cmd.go | 9 ++ vtqe/tools/attach.go | 46 ++++++++ vtqe/tools/base64.go | 61 ++++++++++ vtqe/tools/cmd.go | 18 +++ vtqe/tools/curl.go | 210 ++++++++++++++++++++++++++++++++++ vtqe/tools/detach.go | 48 ++++++++ vtqe/tools/ftp.go | 50 ++++++++ vtqe/tools/generate.go | 39 +++++++ vtqe/tools/hash.go | 71 ++++++++++++ vtqe/tools/http.go | 192 +++++++++++++++++++++++++++++++ vtqe/tools/merge.go | 48 ++++++++ vtqe/tools/ping/fqdn.go | 17 +++ vtqe/tools/ping/http.go | 120 +++++++++++++++++++ vtqe/tools/ping/ping.go | 149 ++++++++++++++++++++++++ vtqe/tools/ping/tcp.go | 102 +++++++++++++++++ vtqe/tools/ping/utils.go | 51 +++++++++ vtqe/tools/ping/utils_test.go | 43 +++++++ vtqe/tools/sftp.go | 77 +++++++++++++ vtqe/tools/split.go | 61 ++++++++++ vtqe/tools/tcping.go | 181 +++++++++++++++++++++++++++++ vtqe/tools/uac.go | 33 ++++++ vtqe/tools/vic.go | 97 ++++++++++++++++ 23 files changed, 1728 insertions(+) create mode 100644 main.go create mode 100644 vtqe/cmd.go create mode 100644 vtqe/tools/attach.go create mode 100644 vtqe/tools/base64.go create mode 100644 vtqe/tools/cmd.go create mode 100644 vtqe/tools/curl.go create mode 100644 vtqe/tools/detach.go create mode 100644 vtqe/tools/ftp.go create mode 100644 vtqe/tools/generate.go create mode 100644 vtqe/tools/hash.go create mode 100644 vtqe/tools/http.go create mode 100644 vtqe/tools/merge.go create mode 100644 vtqe/tools/ping/fqdn.go create mode 100644 vtqe/tools/ping/http.go create mode 100644 vtqe/tools/ping/ping.go create mode 100644 vtqe/tools/ping/tcp.go create mode 100644 vtqe/tools/ping/utils.go create mode 100644 vtqe/tools/ping/utils_test.go create mode 100644 vtqe/tools/sftp.go create mode 100644 vtqe/tools/split.go create mode 100644 vtqe/tools/tcping.go create mode 100644 vtqe/tools/uac.go create mode 100644 vtqe/tools/vic.go diff --git a/main.go b/main.go new file mode 100644 index 0000000..d3103f9 --- /dev/null +++ b/main.go @@ -0,0 +1,5 @@ +package main + +func main() { + +} \ No newline at end of file diff --git a/vtqe/cmd.go b/vtqe/cmd.go new file mode 100644 index 0000000..5e50199 --- /dev/null +++ b/vtqe/cmd.go @@ -0,0 +1,9 @@ +package main + +import ( + "Victorique/vtqe/tools" +) + +func main() { + tools.Maincmd.Execute() +} diff --git a/vtqe/tools/attach.go b/vtqe/tools/attach.go new file mode 100644 index 0000000..4a23174 --- /dev/null +++ b/vtqe/tools/attach.go @@ -0,0 +1,46 @@ +package tools + +import ( + "fmt" + + "b612.me/starainrt" + "b612.me/starlog" + "github.com/spf13/cobra" +) + +var attachcmd = &cobra.Command{ + Use: "attach", + Short: "合并两个文件", + Long: "合并两个文件", + Run: func(this *cobra.Command, args []string) { + var src, dst, out string + if len(args) == 3 { + src = args[0] + dst = args[1] + out = args[2] + } else { + src, _ = this.Flags().GetString("src") + dst, _ = this.Flags().GetString("dst") + out, _ = this.Flags().GetString("out") + } + if src == "" || dst == "" { + starlog.Println("ERROR PATH", "red", "b") + this.Help() + return + } + cryp := new(starainrt.StarCrypto) + err := cryp.Attach(src, dst, out) + if err != nil { + starlog.Println(err.Error, "red", "b") + } else { + fmt.Println("完成") + } + }, +} + +func init() { + attachcmd.Flags().StringP("src", "s", "", "源文件路径") + attachcmd.Flags().StringP("dst", "d", "", "目标文件路径") + attachcmd.Flags().StringP("out", "o", "", "输出文件路径") + Maincmd.AddCommand(attachcmd) +} diff --git a/vtqe/tools/base64.go b/vtqe/tools/base64.go new file mode 100644 index 0000000..c9f54c7 --- /dev/null +++ b/vtqe/tools/base64.go @@ -0,0 +1,61 @@ +package tools + +import ( + "fmt" + + "b612.me/starainrt" + "b612.me/starlog" + "github.com/spf13/cobra" +) + +var b64cmd = &cobra.Command{ + Use: "base64", + Short: "使用base64处理文件或字符串", + Long: "使用base64处理文件或字符串", + Run: func(this *cobra.Command, args []string) { + var err error + ok, _ := this.Flags().GetBool("file") + de, _ := this.Flags().GetBool("decode") + if len(args) != 1 { + starlog.Println("参数不足,请输入文件地址或字符串", "red", "b") + this.Help() + return + } + shell := func(pect float64) { + if pect == 100 { + fmt.Println("已处理:100.000000%") + } else { + fmt.Printf("已处理:%f%%\r", pect) + } + } + cry := new(starainrt.StarCrypto) + if ok { + path, _ := this.Flags().GetString("path") + if !de { + err = cry.Base64EncodeFile(args[0], path, shell) + } else { + err = cry.Base64DecodeFile(args[0], path, shell) + } + } else { + if !de { + data := cry.Base64Encode([]byte(args[0])) + fmt.Println(data) + } else { + var data []byte + data, err = cry.Base64Decode(args[0]) + fmt.Println(string(data)) + } + } + if err != nil { + starlog.Println(err, "red", "b") + return + } + }, +} + +func init() { + b64cmd.Flags().BoolP("file", "f", false, "base64处理文件") + b64cmd.Flags().StringP("path", "p", "./b64.encode", "指定处理地址,默认为./b64.encode") + b64cmd.Flags().BoolP("decode", "d", false, "base64解码") + Maincmd.AddCommand(b64cmd) +} diff --git a/vtqe/tools/cmd.go b/vtqe/tools/cmd.go new file mode 100644 index 0000000..32a7b4e --- /dev/null +++ b/vtqe/tools/cmd.go @@ -0,0 +1,18 @@ +package tools + +import ( + "github.com/spf13/cobra" +) + +var Version string = "0.1.12" + +var Maincmd = &cobra.Command{ + Use: "", + Short: "Victorique's Small Smart Toolkit", + Long: "Victorique's Small Smart Toolkit", +} + +func init() { + cobra.MousetrapHelpText = "" + Maincmd.Version = Version +} diff --git a/vtqe/tools/curl.go b/vtqe/tools/curl.go new file mode 100644 index 0000000..5901d04 --- /dev/null +++ b/vtqe/tools/curl.go @@ -0,0 +1,210 @@ +package tools + +import ( + "fmt" + "io/ioutil" + "net/http" + "strings" + + "b612.me/starainrt" + + "github.com/spf13/cobra" +) + +var curlcmd = &cobra.Command{ + Use: "curl", + Short: "Curl工具", + Long: "Curl小工具", + Run: func(this *cobra.Command, args []string) { + var method string + var err error + var data []byte + o, _ := this.Flags().GetString("output") + d, _ := this.Flags().GetString("data") + f, _ := this.Flags().GetString("file") + h, _ := this.Flags().GetString("header") + c, _ := this.Flags().GetString("cookie") + b, _ := this.Flags().GetString("cookie-jar") + i, _ := this.Flags().GetBool("include") + x, _ := this.Flags().GetString("proxy") + m, _ := this.Flags().GetInt("max-time") + ua, _ := this.Flags().GetString("user-agent") + connecttimeout, _ := this.Flags().GetInt("connect-timeout") + if len(args) != 1 { + this.Help() + return + } + url := args[0] + shell := func(pect float64) { + if pect == 100 { + fmt.Println("已完成:100.000000%") + } else { + fmt.Printf("已完成:%f%%\r", pect) + } + } + var postdata map[string]string + if d != "" { + postdata = make(map[string]string) + strip := strings.Split(d, "&") + for _, v := range strip { + tmp := strings.Split(v, "=") + if len(tmp) != 2 { + continue + } + postdata[tmp[0]] = tmp[1] + } + } + if len(d) == 0 { + method = "GET" + } else { + method = "POST" + } + tmp := strings.Split(f, ",") + curl := starainrt.NewStarCurl() + curl.TimeOut = m + curl.DialTimeOut = connecttimeout + curl.ReqHeader.Set("User-Agent", "Victorique - B612.ME") + if ua != "" { + curl.ReqHeader.Set("User-Agent", ua) + } + if x != "" { + curl.Proxy = x + } + if h != "" { + head := strings.Split(h, ",") + for _, v := range head { + hp := strings.Split(v, "=") + if len(hp) != 2 { + continue + } + curl.ReqHeader.Set(hp[0], hp[1]) + } + } + if c != "" { + if starainrt.Exists(c) { + ck, err := ioutil.ReadFile(c) + if err != nil { + fmt.Println(err) + return + } + h = strings.TrimSpace(string(ck)) + } + cook := strings.Split(h, ",") + for _, v := range cook { + hp := strings.Split(v, "=") + if len(hp) != 2 { + continue + } + curl.ReqCookies = append(curl.ReqCookies, &http.Cookie{Name: hp[0], Value: hp[1]}) + } + + } + if len(tmp) != 2 && f != "" { + fmt.Println("对file应使用逗号分隔区分文件名和路径") + return + } + if o != "" { + if f != "" { + _, err = curl.CurlWithFile(url, postdata, tmp[0], tmp[1], o, true, shell) + + } else { + err = curl.CurlDataToFile(url, []byte(d), method, o, shell) + + } + if err != nil { + fmt.Println(err) + } + if i { + for k, v := range curl.RespHeader { + for _, v2 := range v { + fmt.Println(k + ":" + v2) + } + } + fmt.Println("\n") + var cookiewriter string + for _, v := range curl.RespCookies { + fmt.Println(v.Name + ":" + v.Value) + if b != "" { + cookiewriter += v.Name + ":" + v.Value + "," + } + } + fmt.Println("\n\n") + if b != "" { + ioutil.WriteFile(b, []byte(cookiewriter), 0755) + } + } + } else { + if f != "" { + data, err = curl.CurlWithFile(url, postdata, tmp[0], tmp[1], "", false, shell) + + } else { + data, err = curl.Curl(url, []byte(d), method) + } + if i { + for k, v := range curl.RespHeader { + for _, v2 := range v { + fmt.Println(k + ":" + v2) + } + } + fmt.Println("\n") + var cookiewriter string + for _, v := range curl.RespCookies { + fmt.Println(v.Name + ":" + v.Value) + if b != "" { + cookiewriter += v.Name + ":" + v.Value + "," + } + } + fmt.Println("\n\n") + if b != "" { + ioutil.WriteFile(b, []byte(cookiewriter), 0755) + } + } + fmt.Println(string(data)) + if err != nil { + fmt.Println(err) + } + } + }, +} + +func init() { + Maincmd.AddCommand(curlcmd) + curlcmd.Flags().StringP("output", "o", "", "写入文件而不是标准输出") + curlcmd.Flags().StringP("data", "d", "", "http postdata数据") + curlcmd.Flags().StringP("file", "f", "", "上传文件的地址") + curlcmd.Flags().StringP("header", "H", "", "使用的header") + curlcmd.Flags().StringP("cookie", "b", "", "使用的cookie") + curlcmd.Flags().StringP("cookie-jar", "c", "", "写入返回的cookie到文件中") + curlcmd.Flags().BoolP("include", "i", false, "显示返回的header与cookie") + curlcmd.Flags().StringP("proxy", "x", "", "使用代理") + curlcmd.Flags().IntP("max-time", "m", 0, "最大传输超时时间") + curlcmd.Flags().Int("connect-timeout", 15, "最大连接建立超时时间") + curlcmd.Flags().StringP("user-agent", "A", "", "UA设置") + curlcmd.AddCommand(curlupcmd) +} + +var curlupcmd = &cobra.Command{ + Use: "upload", + Short: "victorique上传工具", + Long: "victorique上传工具", + Run: func(this *cobra.Command, args []string) { + if len(args) != 2 { + fmt.Println(args, "不合法啊") + return + } + curl := starainrt.NewStarCurl() + curl.TimeOut = 0 + shell := func(pect float64) { + if pect == 100 { + fmt.Println("已完成:100.000000%") + } else { + fmt.Printf("已完成:%f%%\r", pect) + } + } + data, err := curl.CurlWithFile("http://"+args[0]+"/vtqeupload1127", nil, "victorique", args[1], "", false, shell) + fmt.Println(string(data)) + if err != nil { + fmt.Println(err) + } + }, +} diff --git a/vtqe/tools/detach.go b/vtqe/tools/detach.go new file mode 100644 index 0000000..26f0aa2 --- /dev/null +++ b/vtqe/tools/detach.go @@ -0,0 +1,48 @@ +package tools + +import ( + "fmt" + + "b612.me/starainrt" + "b612.me/starlog" + "github.com/spf13/cobra" +) + +var detachcmd = &cobra.Command{ + Use: "detach", + Short: "分离两个文件", + Long: "分离两个文件", + Run: func(this *cobra.Command, args []string) { + var src, dst, out string + if len(args) == 3 { + src = args[0] + dst = args[1] + out = args[2] + } else { + src, _ = this.Flags().GetString("src") + dst, _ = this.Flags().GetString("dst") + out, _ = this.Flags().GetString("out") + } + num, _ := this.Flags().GetInt("num") + if src == "" || dst == "" { + starlog.Println("ERROR PATH", "red", "b") + this.Help() + return + } + cryp := new(starainrt.StarCrypto) + err := cryp.Detach(src, num, dst, out) + if err != nil { + starlog.Println(err.Error, "red", "b") + } else { + fmt.Println("完成") + } + }, +} + +func init() { + detachcmd.Flags().StringP("src", "s", "", "源文件路径") + detachcmd.Flags().StringP("dst", "d", "", "目标文件路径1") + detachcmd.Flags().StringP("out", "o", "", "目标文件路径2") + detachcmd.Flags().IntP("num", "n", 0, "分割开始字节") + Maincmd.AddCommand(detachcmd) +} diff --git a/vtqe/tools/ftp.go b/vtqe/tools/ftp.go new file mode 100644 index 0000000..b571145 --- /dev/null +++ b/vtqe/tools/ftp.go @@ -0,0 +1,50 @@ +package tools + +import ( + "log" + "path/filepath" + + filedriver "github.com/goftp/file-driver" + "github.com/goftp/server" + "github.com/spf13/cobra" +) + +var ports int +var username, pwd string + +// ftpCmd represents the ftp command +var ftpcmd = &cobra.Command{ + Use: "ftp", + Short: `FTP文件服务器`, + Long: `FTP文件服务器`, + Run: func(cmd *cobra.Command, args []string) { + path, _ = filepath.Abs(path) + factory := &filedriver.FileDriverFactory{ + RootPath: path, + Perm: server.NewSimplePerm("user", "group"), + } + opts := &server.ServerOpts{ + Factory: factory, + Port: ports, + Hostname: ip, + Auth: &server.SimpleAuth{Name: username, Password: pwd}, + } + + log.Printf("Starting ftp server on %v:%v", opts.Hostname, opts.Port) + log.Printf("Username %v, Password %v", username, pwd) + server := server.NewServer(opts) + err := server.ListenAndServe() + if err != nil { + log.Fatal("Error starting server:", err) + } + }, +} + +func init() { + Maincmd.AddCommand(ftpcmd) + ftpcmd.Flags().IntVarP(&ports, "port", "p", 21, "监听端口") + ftpcmd.Flags().StringVarP(&ip, "ip", "i", "0.0.0.0", "监听地址") + ftpcmd.Flags().StringVarP(&username, "user", "u", "1", "用户名,默认为1") + ftpcmd.Flags().StringVarP(&pwd, "pwd", "k", "1", "密码,默认为1") + ftpcmd.Flags().StringVarP(&path, "folder", "f", "./", "本地文件地址") +} diff --git a/vtqe/tools/generate.go b/vtqe/tools/generate.go new file mode 100644 index 0000000..2fd5828 --- /dev/null +++ b/vtqe/tools/generate.go @@ -0,0 +1,39 @@ +package tools + +import ( + "fmt" + + "b612.me/starainrt" + "github.com/spf13/cobra" +) + +var gencmd = &cobra.Command{ + Use: "generate", + Short: "生成随机文件", + Long: "生成指定大小的随机文件", + Run: func(this *cobra.Command, args []string) { + sum, _ := this.Flags().GetInt("sum") + num, _ := this.Flags().GetInt("num") + if len(args) != 1 { + this.Help() + return + } + err := starainrt.FillWithRandom(args[0], num, 1024*1024, sum, func(pect float64) { + if pect == 100 { + fmt.Println("文件已处理:100.000000%") + } else { + fmt.Printf("文件已处理:%f%%\r", pect) + } + }) + if err != nil { + fmt.Println("err:" + err.Error()) + } + }, +} + +func init() { + gencmd.Flags().IntP("sum", "s", 3, "随机的种子组数") + gencmd.Flags().IntP("num", "n", 1024, "生成的文件大小") + gencmd.MarkFlagRequired("num") + Maincmd.AddCommand(gencmd) +} diff --git a/vtqe/tools/hash.go b/vtqe/tools/hash.go new file mode 100644 index 0000000..117bde9 --- /dev/null +++ b/vtqe/tools/hash.go @@ -0,0 +1,71 @@ +package tools + +import ( + "fmt" + "os" + + "b612.me/starainrt" + + "b612.me/starlog" + "github.com/spf13/cobra" +) + +var hashcmd = &cobra.Command{ + Use: "hash", + Short: "多种方法哈希值校验", + Long: "进行多种方法哈希值校验", + Run: func(this *cobra.Command, args []string) { + var cumethod, method []string + var result map[string]string + var err error + crypto := new(starainrt.StarCrypto) + cumethod = []string{"md5", "crc32", "sha512", "sha384", "sha256", "sha224", "sha1"} + if ok, _ := this.Flags().GetBool("all"); ok { + method = cumethod + } else { + if len(args) == 0 { + this.Usage() + os.Exit(1) + } + + for _, v := range cumethod { + if ok, _ := this.Flags().GetBool(v); ok { + method = append(method, v) + } + } + if len(method) == 0 { + method = append(method, "md5") + } + } + if ok, _ := this.Flags().GetBool("file"); ok { + result, err = crypto.FileSumAll(args[0], method, func(pect float64) { + if pect != 100.0 { + fmt.Printf("校验已完成:%f%%\r", pect) + } else { + fmt.Printf("校验已完成:%f%%\n", pect) + } + }) + } else { + result, err = crypto.SumAll([]byte(args[0]), method) + } + if err != nil { + starlog.Println("错误:"+err.Error(), "red", "") + } + for _, v := range method { + fmt.Printf("%s:%s\n", v, result[v]) + } + }, +} + +func init() { + hashcmd.Flags().BoolP("all", "a", false, "使用所有的校验方法") + hashcmd.Flags().BoolP("file", "f", false, "对指定文件进行校验") + hashcmd.Flags().BoolP("md5", "m", false, "进行MD5校验(默认)") + hashcmd.Flags().BoolP("crc32", "c", false, "进行CRC32校验") + hashcmd.Flags().BoolP("sha512", "s", false, "进行SHA512校验") + hashcmd.Flags().Bool("sha384", false, "进行SHA384校验") + hashcmd.Flags().Bool("sha256", false, "进行SHA256校验") + hashcmd.Flags().Bool("sha224", false, "进行SHA224校验") + hashcmd.Flags().Bool("sha1", false, "进行SHA1校验") + Maincmd.AddCommand(hashcmd) +} diff --git a/vtqe/tools/http.go b/vtqe/tools/http.go new file mode 100644 index 0000000..6b586fb --- /dev/null +++ b/vtqe/tools/http.go @@ -0,0 +1,192 @@ +package tools + +import ( + "fmt" + "io" + "io/ioutil" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + + "b612.me/starainrt" + + "b612.me/starlog" + + "github.com/spf13/cobra" +) + +var port, ip, path string +var up bool + +type TraceHandler struct { + h http.Handler +} + +// httpCmd represents the http command +var httpcmd = &cobra.Command{ + Use: "http", + Short: "HTTP文件服务器", + Long: `HTTP文件服务器`, + Run: func(cmd *cobra.Command, args []string) { + http.HandleFunc("/", httplisten) + path, _ = filepath.Abs(path) + fmt.Println("Listening On Port:" + port) + if up { + fmt.Println("upload is openned,path is /vtqeupload1127") + http.HandleFunc("/vtqeupload1127", uploadfile) + } + err := http.ListenAndServe(ip+":"+port, nil) + if err != nil { + starlog.Println("Error:"+err.Error(), "red", "") + } + }, +} + +func uploadfile(w http.ResponseWriter, r *http.Request) { + if r.Method != "POST" { + w.Write([]byte("USE POST METHOD!")) + return + } + r.ParseMultipartForm(10485760) + file, handler, err := r.FormFile("victorique") + if err != nil { + fmt.Println(err) + w.WriteHeader(502) + w.Write([]byte(err.Error())) + return + } + defer file.Close() + fmt.Printf("Upload %s From %s\n", handler.Filename, r.RemoteAddr) + fmt.Fprintf(w, `
%v
\n")) + if !isroot { + w.Write([]byte(fmt.Sprintf("\n")) + return +} +func init() { + httpcmd.Flags().StringVarP(&port, "port", "p", "80", "监听端口") + httpcmd.Flags().StringVarP(&ip, "ip", "i", "0.0.0.0", "监听ip") + httpcmd.Flags().StringVarP(&path, "folder", "f", "./", "本地文件地址") + httpcmd.Flags().BoolVarP(&up, "upload", "u", false, "是否开启文件上传") + Maincmd.AddCommand(httpcmd) +} diff --git a/vtqe/tools/merge.go b/vtqe/tools/merge.go new file mode 100644 index 0000000..d783c28 --- /dev/null +++ b/vtqe/tools/merge.go @@ -0,0 +1,48 @@ +package tools + +import ( + "fmt" + + "b612.me/starainrt" + "b612.me/starlog" + + "github.com/spf13/cobra" +) + +var mergecmd = &cobra.Command{ + Use: "merge", + Short: "合并文件", + Long: "按路径自动合并分割的文件", + Run: func(this *cobra.Command, args []string) { + var src, dst string + if len(args) == 2 { + src = args[0] + dst = args[1] + } else { + src, _ = this.Flags().GetString("src") + dst, _ = this.Flags().GetString("dst") + } + if src == "" || dst == "" { + this.Help() + return + } + crypto := new(starainrt.StarCrypto) + err := crypto.MergeFile(src, dst, func(pect float64) { + if pect == 100 { + fmt.Println("文件已处理:100.000000%") + } else { + fmt.Printf("文件已处理:%f%%\r", pect) + } + }) + if err != nil { + starlog.Println(err.Error, "red", "") + } + + }, +} + +func init() { + mergecmd.Flags().StringP("src", "s", "", "源文件地址,用*替换文件数字") + mergecmd.Flags().StringP("dst", "d", "", "目标文件地址") + Maincmd.AddCommand(mergecmd) +} diff --git a/vtqe/tools/ping/fqdn.go b/vtqe/tools/ping/fqdn.go new file mode 100644 index 0000000..5f36b48 --- /dev/null +++ b/vtqe/tools/ping/fqdn.go @@ -0,0 +1,17 @@ +package ping + +import "net" + +// GetIP ... +func GetIP(hostname string) string { + addrs, err := net.LookupIP(hostname) + if err != nil { + return "" + } + for _, addr := range addrs { + if ipv4 := addr.To4(); ipv4 != nil { + return ipv4.String() + } + } + return "" +} diff --git a/vtqe/tools/ping/http.go b/vtqe/tools/ping/http.go new file mode 100644 index 0000000..02825ea --- /dev/null +++ b/vtqe/tools/ping/http.go @@ -0,0 +1,120 @@ +package ping + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/httptrace" + "time" +) + +// HTTPing ... +type HTTPing struct { + target *Target + done chan struct{} + result *Result + Method string +} + +var _ Pinger = (*HTTPing)(nil) + +// NewHTTPing return new HTTPing +func NewHTTPing(method string) *HTTPing { + return &HTTPing{ + done: make(chan struct{}), + Method: method, + } +} + +// SetTarget ... +func (ping *HTTPing) SetTarget(target *Target) { + ping.target = target + if ping.result == nil { + ping.result = &Result{Target: target} + } +} + +// Start ping +func (ping *HTTPing) Start() <-chan struct{} { + go func() { + t := time.NewTicker(ping.target.Interval) + defer t.Stop() + for { + select { + case <-t.C: + if ping.result.Counter >= ping.target.Counter && ping.target.Counter != 0 { + ping.Stop() + return + } + duration, resp, remoteAddr, err := ping.ping() + ping.result.Counter++ + + if err != nil { + fmt.Printf("Ping %s - failed: %s\n", ping.target, err) + } else { + defer resp.Body.Close() + length, _ := io.Copy(ioutil.Discard, resp.Body) + fmt.Printf("Ping %s(%s) - %s is open - time=%s method=%s status=%d bytes=%d\n", ping.target, remoteAddr, ping.target.Protocol, duration, ping.Method, resp.StatusCode, length) + if ping.result.MinDuration == 0 { + ping.result.MinDuration = duration + } + if ping.result.MaxDuration == 0 { + ping.result.MaxDuration = duration + } + ping.result.SuccessCounter++ + if duration > ping.result.MaxDuration { + ping.result.MaxDuration = duration + } else if duration < ping.result.MinDuration { + ping.result.MinDuration = duration + } + ping.result.TotalDuration += duration + } + case <-ping.done: + return + } + } + }() + return ping.done +} + +// Result return ping result +func (ping *HTTPing) Result() *Result { + return ping.result +} + +// Stop the tcping +func (ping *HTTPing) Stop() { + ping.done <- struct{}{} +} + +func (ping HTTPing) ping() (time.Duration, *http.Response, string, error) { + var resp *http.Response + var body io.Reader + if ping.Method == "POST" { + body = bytes.NewBufferString("{}") + } + req, err := http.NewRequest(ping.Method, ping.target.String(), body) + req.Header.Set(http.CanonicalHeaderKey("User-Agent"), "tcping") + if err != nil { + return 0, nil, "", err + } + var remoteAddr string + trace := &httptrace.ClientTrace{ + ConnectStart: func(network, addr string) { + remoteAddr = addr + }, + } + req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace)) + duration, errIfce := timeIt(func() interface{} { + client := http.Client{Timeout: ping.target.Timeout} + resp, err = client.Do(req) + return err + }) + if errIfce != nil { + err := errIfce.(error) + return 0, nil, "", err + } + return time.Duration(duration), resp, remoteAddr, nil +} diff --git a/vtqe/tools/ping/ping.go b/vtqe/tools/ping/ping.go new file mode 100644 index 0000000..842514c --- /dev/null +++ b/vtqe/tools/ping/ping.go @@ -0,0 +1,149 @@ +package ping + +import ( + "bytes" + "fmt" + "html/template" + "regexp" + "strconv" + "strings" + "time" +) + +// Protocol ... +type Protocol int + +func (protocol Protocol) String() string { + switch protocol { + case TCP: + return "tcp" + case HTTP: + return "http" + case HTTPS: + return "https" + } + return "unkown" +} + +const ( + // TCP is tcp protocol + TCP Protocol = iota + // HTTP is http protocol + HTTP + // HTTPS is https protocol + HTTPS +) + +// NewProtocol convert protocol stirng to Protocol +func NewProtocol(protocol string) (Protocol, error) { + switch strings.ToLower(protocol) { + case TCP.String(): + return TCP, nil + case HTTP.String(): + return HTTP, nil + case HTTPS.String(): + return HTTPS, nil + } + return 0, fmt.Errorf("protocol %s not support", protocol) +} + +// Target is a ping +type Target struct { + Protocol Protocol + Host string + Port int + + Counter int + Interval time.Duration + Timeout time.Duration +} + +func (target Target) String() string { + return fmt.Sprintf("%s://%s:%d", target.Protocol, target.Host, target.Port) +} + +// Pinger is a ping interface +type Pinger interface { + Start() <-chan struct{} + Stop() + Result() *Result + SetTarget(target *Target) +} + +// Ping is a ping interface +type Ping interface { + Start() <-chan struct{} + + Host() string + Port() int + Protocol() Protocol + Counter() int + + Stop() + + Result() Result +} + +// Result ... +type Result struct { + Counter int + SuccessCounter int + Target *Target + + MinDuration time.Duration + MaxDuration time.Duration + TotalDuration time.Duration +} + +// Avg return the average time of ping +func (result Result) Avg() time.Duration { + if result.SuccessCounter == 0 { + return 0 + } + return result.TotalDuration / time.Duration(result.SuccessCounter) +} + +// Failed return failed counter +func (result Result) Failed() int { + return result.Counter - result.SuccessCounter +} + +func (result Result) String() string { + const resultTpl = ` +Ping statistics {{.Target}} + {{.Counter}} probes sent. + {{.SuccessCounter}} successful, {{.Failed}} failed. +Approximate trip times: + Minimum = {{.MinDuration}}, Maximum = {{.MaxDuration}}, Average = {{.Avg}}` + t := template.Must(template.New("result").Parse(resultTpl)) + res := bytes.NewBufferString("") + t.Execute(res, result) + return res.String() +} + +// CheckURI check uri +func CheckURI(uri string) (schema, host string, port int, matched bool) { + const reExp = `^((?P%s %s
\n", "..", "..", "上层文件夹"))) + } + for _, v := range dir { + if v.Name() != "." || v.Name() != ".." { + if !v.IsDir() { + w.Write([]byte(fmt.Sprintf("%s %d %s
\n", r.URL.Path+"/"+v.Name(), v.Name(), int(v.Size()), v.ModTime().Format("2006-01-02 15:04:05")))) + } else { + w.Write([]byte(fmt.Sprintf("%s %s %s
\n", v.Name(), v.Name(), "文件夹", v.ModTime().Format("2006-01-02 15:04:05")))) + } + } + } + w.Write([]byte("