init.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. package geodata
  2. import (
  3. "context"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "os"
  8. "time"
  9. mihomoHttp "github.com/metacubex/mihomo/component/http"
  10. "github.com/metacubex/mihomo/component/mmdb"
  11. C "github.com/metacubex/mihomo/constant"
  12. "github.com/metacubex/mihomo/log"
  13. )
  14. var (
  15. initGeoSite bool
  16. initGeoIP int
  17. initASN bool
  18. )
  19. func InitGeoSite() error {
  20. if _, err := os.Stat(C.Path.GeoSite()); os.IsNotExist(err) {
  21. log.Infoln("Can't find GeoSite.dat, start download")
  22. if err := downloadGeoSite(C.Path.GeoSite()); err != nil {
  23. return fmt.Errorf("can't download GeoSite.dat: %s", err.Error())
  24. }
  25. log.Infoln("Download GeoSite.dat finish")
  26. initGeoSite = false
  27. }
  28. if !initGeoSite {
  29. if err := Verify(C.GeositeName); err != nil {
  30. log.Warnln("GeoSite.dat invalid, remove and download: %s", err)
  31. if err := os.Remove(C.Path.GeoSite()); err != nil {
  32. return fmt.Errorf("can't remove invalid GeoSite.dat: %s", err.Error())
  33. }
  34. if err := downloadGeoSite(C.Path.GeoSite()); err != nil {
  35. return fmt.Errorf("can't download GeoSite.dat: %s", err.Error())
  36. }
  37. }
  38. initGeoSite = true
  39. }
  40. return nil
  41. }
  42. func downloadGeoSite(path string) (err error) {
  43. ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
  44. defer cancel()
  45. resp, err := mihomoHttp.HttpRequest(ctx, C.GeoSiteUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
  46. if err != nil {
  47. return
  48. }
  49. defer resp.Body.Close()
  50. f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
  51. if err != nil {
  52. return err
  53. }
  54. defer f.Close()
  55. _, err = io.Copy(f, resp.Body)
  56. return err
  57. }
  58. func downloadGeoIP(path string) (err error) {
  59. ctx, cancel := context.WithTimeout(context.Background(), time.Second*90)
  60. defer cancel()
  61. resp, err := mihomoHttp.HttpRequest(ctx, C.GeoIpUrl, http.MethodGet, http.Header{"User-Agent": {C.UA}}, nil)
  62. if err != nil {
  63. return
  64. }
  65. defer resp.Body.Close()
  66. f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)
  67. if err != nil {
  68. return err
  69. }
  70. defer f.Close()
  71. _, err = io.Copy(f, resp.Body)
  72. return err
  73. }
  74. func InitGeoIP() error {
  75. if C.GeodataMode {
  76. if _, err := os.Stat(C.Path.GeoIP()); os.IsNotExist(err) {
  77. log.Infoln("Can't find GeoIP.dat, start download")
  78. if err := downloadGeoIP(C.Path.GeoIP()); err != nil {
  79. return fmt.Errorf("can't download GeoIP.dat: %s", err.Error())
  80. }
  81. log.Infoln("Download GeoIP.dat finish")
  82. initGeoIP = 0
  83. }
  84. if initGeoIP != 1 {
  85. if err := Verify(C.GeoipName); err != nil {
  86. log.Warnln("GeoIP.dat invalid, remove and download: %s", err)
  87. if err := os.Remove(C.Path.GeoIP()); err != nil {
  88. return fmt.Errorf("can't remove invalid GeoIP.dat: %s", err.Error())
  89. }
  90. if err := downloadGeoIP(C.Path.GeoIP()); err != nil {
  91. return fmt.Errorf("can't download GeoIP.dat: %s", err.Error())
  92. }
  93. }
  94. initGeoIP = 1
  95. }
  96. return nil
  97. }
  98. if _, err := os.Stat(C.Path.MMDB()); os.IsNotExist(err) {
  99. log.Infoln("Can't find MMDB, start download")
  100. if err := mmdb.DownloadMMDB(C.Path.MMDB()); err != nil {
  101. return fmt.Errorf("can't download MMDB: %s", err.Error())
  102. }
  103. }
  104. if initGeoIP != 2 {
  105. if !mmdb.Verify(C.Path.MMDB()) {
  106. log.Warnln("MMDB invalid, remove and download")
  107. if err := os.Remove(C.Path.MMDB()); err != nil {
  108. return fmt.Errorf("can't remove invalid MMDB: %s", err.Error())
  109. }
  110. if err := mmdb.DownloadMMDB(C.Path.MMDB()); err != nil {
  111. return fmt.Errorf("can't download MMDB: %s", err.Error())
  112. }
  113. }
  114. initGeoIP = 2
  115. }
  116. return nil
  117. }
  118. func InitASN() error {
  119. if _, err := os.Stat(C.Path.ASN()); os.IsNotExist(err) {
  120. log.Infoln("Can't find ASN.mmdb, start download")
  121. if err := mmdb.DownloadASN(C.Path.ASN()); err != nil {
  122. return fmt.Errorf("can't download ASN.mmdb: %s", err.Error())
  123. }
  124. log.Infoln("Download ASN.mmdb finish")
  125. initASN = false
  126. }
  127. if !initASN {
  128. if !mmdb.Verify(C.Path.ASN()) {
  129. log.Warnln("ASN invalid, remove and download")
  130. if err := os.Remove(C.Path.ASN()); err != nil {
  131. return fmt.Errorf("can't remove invalid ASN: %s", err.Error())
  132. }
  133. if err := mmdb.DownloadASN(C.Path.ASN()); err != nil {
  134. return fmt.Errorf("can't download ASN: %s", err.Error())
  135. }
  136. }
  137. initASN = true
  138. }
  139. return nil
  140. }