fix: 移除ip2region
This commit is contained in:
12
go.mod
12
go.mod
@@ -14,10 +14,10 @@ require (
|
|||||||
github.com/gosnmp/gosnmp v1.35.0
|
github.com/gosnmp/gosnmp v1.35.0
|
||||||
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
|
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f
|
||||||
github.com/matoous/go-nanoid/v2 v2.0.0
|
github.com/matoous/go-nanoid/v2 v2.0.0
|
||||||
github.com/mojocn/base64Captcha v1.3.5
|
github.com/mojocn/base64Captcha v1.3.6
|
||||||
github.com/mssola/user_agent v0.6.0
|
github.com/mssola/user_agent v0.6.0
|
||||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||||
github.com/redis/go-redis/v9 v9.1.0
|
github.com/redis/go-redis/v9 v9.4.0
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/shirou/gopsutil v3.21.11+incompatible
|
github.com/shirou/gopsutil v3.21.11+incompatible
|
||||||
github.com/shirou/gopsutil/v3 v3.23.7
|
github.com/shirou/gopsutil/v3 v3.23.7
|
||||||
@@ -27,8 +27,8 @@ require (
|
|||||||
golang.org/x/crypto v0.12.0
|
golang.org/x/crypto v0.12.0
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gorm.io/driver/mysql v1.5.1
|
gorm.io/driver/mysql v1.5.2
|
||||||
gorm.io/gorm v1.25.2
|
gorm.io/gorm v1.25.5
|
||||||
xorm.io/xorm v1.3.2
|
xorm.io/xorm v1.3.2
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -84,10 +84,10 @@ require (
|
|||||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
|
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect
|
||||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||||
golang.org/x/arch v0.3.0 // indirect
|
golang.org/x/arch v0.3.0 // indirect
|
||||||
golang.org/x/image v0.5.0 // indirect
|
golang.org/x/image v0.13.0 // indirect
|
||||||
golang.org/x/net v0.10.0 // indirect
|
golang.org/x/net v0.10.0 // indirect
|
||||||
golang.org/x/sys v0.11.0 // indirect
|
golang.org/x/sys v0.11.0 // indirect
|
||||||
golang.org/x/text v0.12.0 // indirect
|
golang.org/x/text v0.13.0
|
||||||
google.golang.org/protobuf v1.30.0 // indirect
|
google.golang.org/protobuf v1.30.0 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
|
||||||
|
|||||||
30
go.sum
30
go.sum
@@ -64,8 +64,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
|
|||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||||
github.com/bsm/ginkgo/v2 v2.9.5 h1:rtVBYPs3+TC5iLUVOis1B9tjLTup7Cj5IfzosKtvTJ0=
|
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||||
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
|
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||||
@@ -428,8 +428,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
|
|||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
|
||||||
github.com/mojocn/base64Captcha v1.3.5 h1:Qeilr7Ta6eDtG4S+tQuZ5+hO+QHbiGAJdi4PfoagaA0=
|
github.com/mojocn/base64Captcha v1.3.6 h1:gZEKu1nsKpttuIAQgWHO+4Mhhls8cAKyiV2Ew03H+Tw=
|
||||||
github.com/mojocn/base64Captcha v1.3.5/go.mod h1:/tTTXn4WTpX9CfrmipqRytCpJ27Uw3G6I7NcP2WwcmY=
|
github.com/mojocn/base64Captcha v1.3.6/go.mod h1:i5CtHvm+oMbj1UzEPXaA8IH/xHFZ3DGY3Wh3dBpZ28E=
|
||||||
github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
|
github.com/mssola/user_agent v0.6.0 h1:uwPR4rtWlCHRFyyP9u2KOV0u8iQXmS7Z7feTrstQwk4=
|
||||||
github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
|
github.com/mssola/user_agent v0.6.0/go.mod h1:TTPno8LPY3wAIEKRpAtkdMT0f8SE24pLRGPahjCH4uw=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
@@ -495,8 +495,8 @@ github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R
|
|||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||||
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||||
github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY=
|
github.com/redis/go-redis/v9 v9.4.0 h1:Yzoz33UZw9I/mFhx4MNrB6Fk+XHO1VukNcCa1+lwyKk=
|
||||||
github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c=
|
github.com/redis/go-redis/v9 v9.4.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||||
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM=
|
||||||
@@ -659,10 +659,10 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190501045829-6d32002ffd75/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
|
|
||||||
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
|
||||||
|
golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
|
||||||
|
golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@@ -835,8 +835,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
|
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||||
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -1033,11 +1033,11 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
|
gorm.io/driver/mysql v1.5.2 h1:QC2HRskSE75wBuOxe0+iCkyJZ+RqpudsQtqkp+IMuXs=
|
||||||
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
|
gorm.io/driver/mysql v1.5.2/go.mod h1:pQLhh1Ut/WUAySdTHwBpBv6+JKcj+ua4ZFx1QQTBzb8=
|
||||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||||
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
|
gorm.io/gorm v1.25.5 h1:zR9lOiiYf09VNh5Q1gphfyia1JpiClIWG9hQaxB/mls=
|
||||||
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
gorm.io/gorm v1.25.5/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
|
|||||||
@@ -1,238 +0,0 @@
|
|||||||
package ip2region
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
HeaderInfoLength = 256
|
|
||||||
VectorIndexRows = 256
|
|
||||||
VectorIndexCols = 256
|
|
||||||
VectorIndexSize = 8
|
|
||||||
SegmentIndexBlockSize = 14
|
|
||||||
)
|
|
||||||
|
|
||||||
// --- Index policy define
|
|
||||||
|
|
||||||
type IndexPolicy int
|
|
||||||
|
|
||||||
const (
|
|
||||||
VectorIndexPolicy IndexPolicy = 1
|
|
||||||
BTreeIndexPolicy IndexPolicy = 2
|
|
||||||
)
|
|
||||||
|
|
||||||
func (i IndexPolicy) String() string {
|
|
||||||
switch i {
|
|
||||||
case VectorIndexPolicy:
|
|
||||||
return "VectorIndex"
|
|
||||||
case BTreeIndexPolicy:
|
|
||||||
return "BtreeIndex"
|
|
||||||
default:
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Header define
|
|
||||||
|
|
||||||
type Header struct {
|
|
||||||
// data []byte
|
|
||||||
Version uint16
|
|
||||||
IndexPolicy IndexPolicy
|
|
||||||
CreatedAt uint32
|
|
||||||
StartIndexPtr uint32
|
|
||||||
EndIndexPtr uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewHeader(input []byte) (*Header, error) {
|
|
||||||
if len(input) < 16 {
|
|
||||||
return nil, fmt.Errorf("invalid input buffer")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Header{
|
|
||||||
Version: binary.LittleEndian.Uint16(input),
|
|
||||||
IndexPolicy: IndexPolicy(binary.LittleEndian.Uint16(input[2:])),
|
|
||||||
CreatedAt: binary.LittleEndian.Uint32(input[4:]),
|
|
||||||
StartIndexPtr: binary.LittleEndian.Uint32(input[8:]),
|
|
||||||
EndIndexPtr: binary.LittleEndian.Uint32(input[12:]),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- searcher implementation
|
|
||||||
|
|
||||||
type Searcher struct {
|
|
||||||
handle *os.File
|
|
||||||
|
|
||||||
ioCount int
|
|
||||||
|
|
||||||
// use it only when this feature enabled.
|
|
||||||
// Preload the vector index will reduce the number of IO operations
|
|
||||||
// thus speedup the search process
|
|
||||||
vectorIndex []byte
|
|
||||||
|
|
||||||
// content buffer.
|
|
||||||
// running with the whole xdb file cached
|
|
||||||
contentBuff []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func baseNew(dbFile string, vIndex []byte, cBuff []byte) (*Searcher, error) {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// content buff first
|
|
||||||
if cBuff != nil {
|
|
||||||
return &Searcher{
|
|
||||||
vectorIndex: nil,
|
|
||||||
contentBuff: cBuff,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// open the xdb binary file
|
|
||||||
handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Searcher{
|
|
||||||
handle: handle,
|
|
||||||
vectorIndex: vIndex,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWithFileOnly(dbFile string) (*Searcher, error) {
|
|
||||||
return baseNew(dbFile, nil, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWithVectorIndex(dbFile string, vIndex []byte) (*Searcher, error) {
|
|
||||||
return baseNew(dbFile, vIndex, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewWithBuffer(cBuff []byte) (*Searcher, error) {
|
|
||||||
return baseNew("", nil, cBuff)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Searcher) Close() {
|
|
||||||
if s.handle != nil {
|
|
||||||
err := s.handle.Close()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetIOCount return the global io count for the last search
|
|
||||||
func (s *Searcher) GetIOCount() int {
|
|
||||||
return s.ioCount
|
|
||||||
}
|
|
||||||
|
|
||||||
// SearchByStr find the region for the specified ip string
|
|
||||||
func (s *Searcher) SearchByStr(str string) (string, error) {
|
|
||||||
ip, err := CheckIP(str)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.Search(ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Search find the region for the specified long ip
|
|
||||||
func (s *Searcher) Search(ip uint32) (string, error) {
|
|
||||||
// reset the global ioCount
|
|
||||||
s.ioCount = 0
|
|
||||||
|
|
||||||
// locate the segment index block based on the vector index
|
|
||||||
var il0 = (ip >> 24) & 0xFF
|
|
||||||
var il1 = (ip >> 16) & 0xFF
|
|
||||||
var idx = il0*VectorIndexCols*VectorIndexSize + il1*VectorIndexSize
|
|
||||||
var sPtr, ePtr = uint32(0), uint32(0)
|
|
||||||
if s.vectorIndex != nil {
|
|
||||||
sPtr = binary.LittleEndian.Uint32(s.vectorIndex[idx:])
|
|
||||||
ePtr = binary.LittleEndian.Uint32(s.vectorIndex[idx+4:])
|
|
||||||
} else if s.contentBuff != nil {
|
|
||||||
sPtr = binary.LittleEndian.Uint32(s.contentBuff[HeaderInfoLength+idx:])
|
|
||||||
ePtr = binary.LittleEndian.Uint32(s.contentBuff[HeaderInfoLength+idx+4:])
|
|
||||||
} else {
|
|
||||||
// read the vector index block
|
|
||||||
var buff = make([]byte, VectorIndexSize)
|
|
||||||
err := s.read(int64(HeaderInfoLength+idx), buff)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("read vector index block at %d: %w", HeaderInfoLength+idx, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
sPtr = binary.LittleEndian.Uint32(buff)
|
|
||||||
ePtr = binary.LittleEndian.Uint32(buff[4:])
|
|
||||||
}
|
|
||||||
|
|
||||||
// fmt.Printf("sPtr=%d, ePtr=%d", sPtr, ePtr)
|
|
||||||
|
|
||||||
// binary search the segment index to get the region
|
|
||||||
var dataLen, dataPtr = 0, uint32(0)
|
|
||||||
var buff = make([]byte, SegmentIndexBlockSize)
|
|
||||||
var l, h = 0, int((ePtr - sPtr) / SegmentIndexBlockSize)
|
|
||||||
for l <= h {
|
|
||||||
m := (l + h) >> 1
|
|
||||||
p := sPtr + uint32(m*SegmentIndexBlockSize)
|
|
||||||
err := s.read(int64(p), buff)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("read segment index at %d: %w", p, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// decode the data step by step to reduce the unnecessary operations
|
|
||||||
sip := binary.LittleEndian.Uint32(buff)
|
|
||||||
if ip < sip {
|
|
||||||
h = m - 1
|
|
||||||
} else {
|
|
||||||
eip := binary.LittleEndian.Uint32(buff[4:])
|
|
||||||
if ip > eip {
|
|
||||||
l = m + 1
|
|
||||||
} else {
|
|
||||||
dataLen = int(binary.LittleEndian.Uint16(buff[8:]))
|
|
||||||
dataPtr = binary.LittleEndian.Uint32(buff[10:])
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//fmt.Printf("dataLen: %d, dataPtr: %d", dataLen, dataPtr)
|
|
||||||
if dataLen == 0 {
|
|
||||||
return "", nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// load and return the region data
|
|
||||||
var regionBuff = make([]byte, dataLen)
|
|
||||||
err := s.read(int64(dataPtr), regionBuff)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("read region at %d: %w", dataPtr, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return string(regionBuff), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// do the data read operation based on the setting.
|
|
||||||
// content buffer first or will read from the file.
|
|
||||||
// this operation will invoke the Seek for file based read.
|
|
||||||
func (s *Searcher) read(offset int64, buff []byte) error {
|
|
||||||
if s.contentBuff != nil {
|
|
||||||
cLen := copy(buff, s.contentBuff[offset:])
|
|
||||||
if cLen != len(buff) {
|
|
||||||
return fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_, err := s.handle.Seek(offset, 0)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("seek to %d: %w", offset, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.ioCount++
|
|
||||||
rLen, err := s.handle.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("handle read: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rLen != len(buff) {
|
|
||||||
return fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,59 +1,12 @@
|
|||||||
package ip2region
|
package ip2region
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"embed"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"ems.agt/src/framework/logger"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// 网络地址(内网)
|
// 网络地址(内网)
|
||||||
const LOCAT_HOST = "127.0.0.1"
|
const LOCAT_HOST = "127.0.0.1"
|
||||||
|
|
||||||
// 全局查询对象
|
|
||||||
var searcher *Searcher
|
|
||||||
|
|
||||||
//go:embed ip2region.xdb
|
|
||||||
var ip2regionDB embed.FS
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
// 从 dbPath 加载整个 xdb 到内存
|
|
||||||
buf, err := ip2regionDB.ReadFile("ip2region.xdb")
|
|
||||||
if err != nil {
|
|
||||||
logger.Fatalf("failed error load xdb from : %s\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用全局的 cBuff 创建完全基于内存的查询对象。
|
|
||||||
base, err := NewWithBuffer(buf)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("failed error create searcher with content: %s\n", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 赋值到全局查询对象
|
|
||||||
searcher = base
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegionSearchByIp 查询IP所在地
|
|
||||||
//
|
|
||||||
// 国家|区域|省份|城市|ISP
|
|
||||||
func RegionSearchByIp(ip string) (string, int, int64) {
|
|
||||||
ip = ClientIP(ip)
|
|
||||||
if ip == LOCAT_HOST {
|
|
||||||
// "0|0|0|内网IP|内网IP"
|
|
||||||
return "0|0|0|app.common.noIPregion|app.common.noIPregion", 0, 0
|
|
||||||
}
|
|
||||||
tStart := time.Now()
|
|
||||||
region, err := searcher.SearchByStr(ip)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("failed to SearchIP(%s): %s\n", ip, err)
|
|
||||||
return "0|0|0|0|0", 0, 0
|
|
||||||
}
|
|
||||||
return region, 0, time.Since(tStart).Milliseconds()
|
|
||||||
}
|
|
||||||
|
|
||||||
// RealAddressByIp 地址IP所在地
|
// RealAddressByIp 地址IP所在地
|
||||||
//
|
//
|
||||||
// 218.4.167.70 江苏省 苏州市
|
// 218.4.167.70 江苏省 苏州市
|
||||||
@@ -62,22 +15,8 @@ func RealAddressByIp(ip string) string {
|
|||||||
if ip == LOCAT_HOST {
|
if ip == LOCAT_HOST {
|
||||||
return "app.common.noIPregion" // 内网IP
|
return "app.common.noIPregion" // 内网IP
|
||||||
}
|
}
|
||||||
region, err := searcher.SearchByStr(ip)
|
|
||||||
if err != nil {
|
|
||||||
logger.Errorf("failed to SearchIP(%s): %s\n", ip, err)
|
|
||||||
return "app.common.unknown" // 未知
|
|
||||||
}
|
|
||||||
parts := strings.Split(region, "|")
|
|
||||||
province := parts[2]
|
|
||||||
city := parts[3]
|
|
||||||
if province == "0" && city != "0" {
|
|
||||||
if city == "内网IP" {
|
|
||||||
return "app.common.noIPregion" // 内网IP
|
return "app.common.noIPregion" // 内网IP
|
||||||
}
|
}
|
||||||
return city
|
|
||||||
}
|
|
||||||
return province + " " + city
|
|
||||||
}
|
|
||||||
|
|
||||||
// ClientIP 处理客户端IP地址显示iPv4
|
// ClientIP 处理客户端IP地址显示iPv4
|
||||||
//
|
//
|
||||||
|
|||||||
Binary file not shown.
@@ -1,175 +0,0 @@
|
|||||||
package ip2region
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
var shiftIndex = []int{24, 16, 8, 0}
|
|
||||||
|
|
||||||
func CheckIP(ip string) (uint32, error) {
|
|
||||||
var ps = strings.Split(strings.TrimSpace(ip), ".")
|
|
||||||
if len(ps) != 4 {
|
|
||||||
return 0, fmt.Errorf("invalid ip address `%s`", ip)
|
|
||||||
}
|
|
||||||
|
|
||||||
var val = uint32(0)
|
|
||||||
for i, s := range ps {
|
|
||||||
d, err := strconv.Atoi(s)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("the %dth part `%s` is not an integer", i, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
if d < 0 || d > 255 {
|
|
||||||
return 0, fmt.Errorf("the %dth part `%s` should be an integer bettween 0 and 255", i, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
val |= uint32(d) << shiftIndex[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert the ip to integer
|
|
||||||
return val, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Long2IP(ip uint32) string {
|
|
||||||
return fmt.Sprintf("%d.%d.%d.%d", (ip>>24)&0xFF, (ip>>16)&0xFF, (ip>>8)&0xFF, ip&0xFF)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MidIP(sip uint32, eip uint32) uint32 {
|
|
||||||
return uint32((uint64(sip) + uint64(eip)) >> 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadHeader load the header info from the specified handle
|
|
||||||
func LoadHeader(handle *os.File) (*Header, error) {
|
|
||||||
_, err := handle.Seek(0, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("seek to the header: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buff = make([]byte, HeaderInfoLength)
|
|
||||||
rLen, err := handle.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rLen != len(buff) {
|
|
||||||
return nil, fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
|
|
||||||
}
|
|
||||||
|
|
||||||
return NewHeader(buff)
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadHeaderFromFile load header info from the specified db file path
|
|
||||||
func LoadHeaderFromFile(dbFile string) (*Header, error) {
|
|
||||||
handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("open xdb file `%s`: %w", dbFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func(handle *os.File) {
|
|
||||||
_ = handle.Close()
|
|
||||||
}(handle)
|
|
||||||
|
|
||||||
header, err := LoadHeader(handle)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return header, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadHeaderFromBuff wrap the header info from the content buffer
|
|
||||||
func LoadHeaderFromBuff(cBuff []byte) (*Header, error) {
|
|
||||||
return NewHeader(cBuff[0:256])
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadVectorIndex util function to load the vector index from the specified file handle
|
|
||||||
func LoadVectorIndex(handle *os.File) ([]byte, error) {
|
|
||||||
// load all the vector index block
|
|
||||||
_, err := handle.Seek(HeaderInfoLength, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("seek to vector index: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buff = make([]byte, VectorIndexRows*VectorIndexCols*VectorIndexSize)
|
|
||||||
rLen, err := handle.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rLen != len(buff) {
|
|
||||||
return nil, fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
|
|
||||||
}
|
|
||||||
|
|
||||||
return buff, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadVectorIndexFromFile load vector index from a specified file path
|
|
||||||
func LoadVectorIndexFromFile(dbFile string) ([]byte, error) {
|
|
||||||
handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("open xdb file `%s`: %w", dbFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_ = handle.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
vIndex, err := LoadVectorIndex(handle)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return vIndex, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadContent load the whole xdb content from the specified file handle
|
|
||||||
func LoadContent(handle *os.File) ([]byte, error) {
|
|
||||||
// get file size
|
|
||||||
fi, err := handle.Stat()
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("stat: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
size := fi.Size()
|
|
||||||
|
|
||||||
// seek to the head of the file
|
|
||||||
_, err = handle.Seek(0, 0)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("seek to get xdb file length: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var buff = make([]byte, size)
|
|
||||||
rLen, err := handle.Read(buff)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if rLen != len(buff) {
|
|
||||||
return nil, fmt.Errorf("incomplete read: readed bytes should be %d", len(buff))
|
|
||||||
}
|
|
||||||
|
|
||||||
return buff, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadContentFromFile load the whole xdb content from the specified db file path
|
|
||||||
func LoadContentFromFile(dbFile string) ([]byte, error) {
|
|
||||||
handle, err := os.OpenFile(dbFile, os.O_RDONLY, 0600)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("open xdb file `%s`: %w", dbFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_ = handle.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
cBuff, err := LoadContent(handle)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cBuff, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user