diff --git a/ipgeo/chunzhen.go b/ipgeo/chunzhen.go index 8326892..2e4a711 100644 --- a/ipgeo/chunzhen.go +++ b/ipgeo/chunzhen.go @@ -10,11 +10,11 @@ import ( "time" ) -func Chunzhen(ip string) (*IPGeoData, error) { +func Chunzhen(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { url := util.GetenvDefault("NEXTTRACE_CHUNZHENURL", "http://127.0.0.1:2060") + "?ip=" + ip client := &http.Client{ // 2 秒超时 - Timeout: 2 * time.Second, + Timeout: timeout, } req, _ := http.NewRequest("GET", url, nil) content, err := client.Do(req) diff --git a/ipgeo/dn42.go b/ipgeo/dn42.go index d6eebea..6c0355e 100644 --- a/ipgeo/dn42.go +++ b/ipgeo/dn42.go @@ -2,6 +2,7 @@ package ipgeo import ( "strings" + "time" "github.com/xgadget-lab/nexttrace/dn42" ) @@ -18,7 +19,7 @@ func LtdCodeToCountryOrAreaName(Code string) string { return Code } -func DN42(ip string) (*IPGeoData, error) { +func DN42(ip string, _ time.Duration, _ string, _ bool) (*IPGeoData, error) { data := &IPGeoData{} // 先解析传入过来的数据 ipTmp := strings.Split(ip, ",") diff --git a/ipgeo/ip2region.go b/ipgeo/ip2region.go index 41ae0c0..2e335b7 100644 --- a/ipgeo/ip2region.go +++ b/ipgeo/ip2region.go @@ -6,6 +6,7 @@ import ( "io" "net/http" "os" + "time" "github.com/lionsoul2014/ip2region/v1.0/binding/golang/ip2region" ) @@ -36,7 +37,7 @@ func downloadDataBase() error { return err } -func IP2Region(ip string) (*IPGeoData, error) { +func IP2Region(ip string, _ time.Duration, _ string, _ bool) (*IPGeoData, error) { if _, err := os.Stat(ipDataBasePath); os.IsNotExist(err) { if err = downloadDataBase(); err != nil { panic("Download Failed!") diff --git a/ipgeo/ipapicom.go b/ipgeo/ipapicom.go index f2809a0..131e9bf 100644 --- a/ipgeo/ipapicom.go +++ b/ipgeo/ipapicom.go @@ -11,11 +11,11 @@ import ( "github.com/tidwall/gjson" ) -func IPApiCom(ip string) (*IPGeoData, error) { +func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,as" client := &http.Client{ // 2 秒超时 - Timeout: 2 * time.Second, + Timeout: timeout, } req, _ := http.NewRequest("GET", url, nil) req.Header.Set("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0") diff --git a/ipgeo/ipgeo.go b/ipgeo/ipgeo.go index 14aeb00..ec6923e 100644 --- a/ipgeo/ipgeo.go +++ b/ipgeo/ipgeo.go @@ -2,6 +2,7 @@ package ipgeo import ( "strings" + "time" ) type IPGeoData struct { @@ -25,7 +26,7 @@ type IPGeoData struct { Source string `json:"source"` } -type Source = func(ip string) (*IPGeoData, error) +type Source = func(ip string, timeout time.Duration, lang string, maptrace bool) (*IPGeoData, error) func GetSource(s string) Source { switch strings.ToUpper(s) { @@ -56,6 +57,6 @@ func GetSource(s string) Source { } } -func disableGeoIP(ip string) (*IPGeoData, error) { +func disableGeoIP(string, time.Duration, string, bool) (*IPGeoData, error) { return &IPGeoData{}, nil } diff --git a/ipgeo/ipinfo.go b/ipgeo/ipinfo.go index 3b27ee8..0c745a6 100644 --- a/ipgeo/ipinfo.go +++ b/ipgeo/ipinfo.go @@ -4,12 +4,19 @@ import ( "io" "net/http" "strings" + "time" "github.com/tidwall/gjson" ) -func IPInfo(ip string) (*IPGeoData, error) { - resp, err := http.Get("https://ipinfo.io/" + ip + "?token=" + token.ipinfo) +func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { + url := "https://ipinfo.io/" + ip + "?token=" + token.ipinfo + client := &http.Client{ + // 2 秒超时 + Timeout: timeout, + } + resp, err := client.Get(url) + //resp, err := http.Get("https://ipinfo.io/" + ip + "?token=" + token.ipinfo) if err != nil { return nil, err } diff --git a/ipgeo/ipinfoLocal.go b/ipgeo/ipinfoLocal.go index a3d75c0..b897017 100644 --- a/ipgeo/ipinfoLocal.go +++ b/ipgeo/ipinfoLocal.go @@ -6,13 +6,14 @@ import ( "net" "os" "strings" + "time" ) const ( ipinfoDataBasePath = "./ipinfoLocal.mmdb" ) -func IPInfoLocal(ip string) (*IPGeoData, error) { +func IPInfoLocal(ip string, _ time.Duration, _ string, _ bool) (*IPGeoData, error) { if _, err := os.Stat(ipinfoDataBasePath); os.IsNotExist(err) { panic("Cannot find ipinfoLocal.mmdb") } diff --git a/ipgeo/ipinsight.go b/ipgeo/ipinsight.go index ea62d2d..0e7cfda 100644 --- a/ipgeo/ipinsight.go +++ b/ipgeo/ipinsight.go @@ -3,12 +3,17 @@ package ipgeo import ( "io" "net/http" + "time" "github.com/tidwall/gjson" ) -func IPInSight(ip string) (*IPGeoData, error) { - resp, err := http.Get("https://api.ipinsight.io/ip/" + ip + "?token=" + token.ipinsight) +func IPInSight(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { + client := &http.Client{ + // 2 秒超时 + Timeout: timeout, + } + resp, err := client.Get("https://api.ipinsight.io/ip/" + ip + "?token=" + token.ipinsight) if err != nil { return nil, err } diff --git a/ipgeo/ipsb.go b/ipgeo/ipsb.go index 368f380..1d9fbad 100644 --- a/ipgeo/ipsb.go +++ b/ipgeo/ipsb.go @@ -10,11 +10,11 @@ import ( "github.com/tidwall/gjson" ) -func IPSB(ip string) (*IPGeoData, error) { +func IPSB(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) { url := "https://api.ip.sb/geoip/" + ip client := &http.Client{ // 2 秒超时 - Timeout: 2 * time.Second, + Timeout: timeout, } req, _ := http.NewRequest("GET", url, nil) // 设置 UA,ip.sb 默认禁止 go-client User-Agent 的 api 请求 diff --git a/ipgeo/leo.go b/ipgeo/leo.go index efdcc3f..b27954c 100644 --- a/ipgeo/leo.go +++ b/ipgeo/leo.go @@ -80,7 +80,12 @@ func receiveParse() { } } -func LeoIP(ip string) (*IPGeoData, error) { +func LeoIP(ip string, timeout time.Duration, lang string, maptrace bool) (*IPGeoData, error) { + //TODO: 根据lang的值请求中文/英文API + //TODO: 根据maptrace的值决定是否请求经纬度信息 + if timeout < 5*time.Second { + timeout = 5 * time.Second + } // 初始化通道 - 向池子里添加IP的Channel,返回IP数据是通过字典中对应键为IP的Channel来获取的 IPPools.poolMux.Lock() defer IPPools.poolMux.Unlock() @@ -99,7 +104,7 @@ func LeoIP(ip string) (*IPGeoData, error) { case res := <-IPPools.pool[ip]: return &res, nil // 5秒后依旧没有接收到返回的IP数据,不再等待,超时异常处理 - case <-time.After(5 * time.Second): + case <-time.After(timeout): // default: // 这里不可以返回一个 nil,否则在访问对象内部的键值的时候会报空指针的 Fatal Error return &IPGeoData{}, errors.New("TimeOut") diff --git a/printer/basic.go b/printer/basic.go index a551ad8..dc835a2 100644 --- a/printer/basic.go +++ b/printer/basic.go @@ -12,6 +12,10 @@ var version = "v0.0.0.alpha" var buildDate = "" var commitID = "" +func GetVersion() string { + return version +} + func Version() { fmt.Fprintf(color.Output, "%s %s %s %s\n", color.New(color.FgWhite, color.Bold).Sprintf("%s", "NextTrace"), diff --git a/trace/trace.go b/trace/trace.go index aca0f68..fdb7418 100644 --- a/trace/trace.go +++ b/trace/trace.go @@ -35,6 +35,7 @@ type Config struct { RealtimePrinter func(res *Result, ttl int) AsyncPrinter func(res *Result) PktSize int + Maptrace bool } type Method string @@ -133,7 +134,7 @@ func (h *Hop) fetchIPData(c Config) (err error) { h.Hostname = r[0][:len(r[0])-1] ip = h.Address.String() + "," + h.Hostname } - h.Geo, err = c.IPGeoSource(ip) + h.Geo, err = c.IPGeoSource(ip, c.Timeout, c.Lang, c.Maptrace) return nil } @@ -166,7 +167,11 @@ func (h *Hop) fetchIPData(c Config) (err error) { h.Lang = c.Lang h.Geo, res = ipgeo.Filter(h.Address.String()) if !res { - h.Geo, err = c.IPGeoSource(h.Address.String()) + timeout := c.Timeout + if c.Timeout < 2*time.Second { + timeout = 2 * time.Second + } + h.Geo, err = c.IPGeoSource(h.Address.String(), timeout, c.Lang, c.Maptrace) } } // Fetch Done diff --git a/wshandle/client.go b/wshandle/client.go index b8bade1..95b9faf 100644 --- a/wshandle/client.go +++ b/wshandle/client.go @@ -2,12 +2,15 @@ package wshandle import ( "crypto/tls" + "fmt" + "github.com/xgadget-lab/nexttrace/printer" "log" "net" "net/http" "net/url" "os" "os/signal" + "runtime" "strings" "sync" "time" @@ -119,7 +122,8 @@ func (c *WsConn) recreateWsConn() { u := url.URL{Scheme: "wss", Host: fast_ip + ":" + port, Path: "/v2/ipGeoWs"} // log.Printf("connecting to %s", u.String()) requestHeader := http.Header{ - "Host": []string{host}, + "Host": []string{host}, + "User-Agent": []string{fmt.Sprintf("NextTrace %s/%s/%s", printer.GetVersion(), runtime.GOOS, runtime.GOARCH)}, } dialer := websocket.DefaultDialer dialer.TLSClientConfig = &tls.Config{ @@ -177,7 +181,8 @@ func createWsConn() *WsConn { } // 判断是否是一个 IP requestHeader := http.Header{ - "Host": []string{host}, + "Host": []string{host}, + "User-Agent": []string{fmt.Sprintf("NextTrace %s/%s/%s", printer.GetVersion(), runtime.GOOS, runtime.GOARCH)}, } dialer := websocket.DefaultDialer dialer.TLSClientConfig = &tls.Config{