@@ -13,7 +13,9 @@ import (
13
13
"github.com/metacubex/mihomo/component/geodata"
14
14
_ "github.com/metacubex/mihomo/component/geodata/standard"
15
15
"github.com/metacubex/mihomo/component/mmdb"
16
+ "github.com/metacubex/mihomo/component/resource"
16
17
C "github.com/metacubex/mihomo/constant"
18
+ P "github.com/metacubex/mihomo/constant/provider"
17
19
"github.com/metacubex/mihomo/log"
18
20
19
21
"github.com/oschwald/maxminddb-golang"
@@ -43,73 +45,122 @@ func SetGeoUpdateInterval(newGeoUpdateInterval int) {
43
45
}
44
46
45
47
func UpdateMMDB () (err error ) {
46
- defer mmdb .ReloadIP ()
47
- data , err := downloadForBytes (geodata .MmdbUrl ())
48
+ vehicle := resource .NewHTTPVehicle (geodata .MmdbUrl (), C .Path .MMDB (), "" , nil , defaultHttpTimeout )
49
+ var oldHash P.HashType
50
+ if buf , err := os .ReadFile (vehicle .Path ()); err == nil {
51
+ oldHash = P .MakeHash (buf )
52
+ }
53
+ data , hash , err := vehicle .Read (context .Background (), oldHash )
48
54
if err != nil {
49
55
return fmt .Errorf ("can't download MMDB database file: %w" , err )
50
56
}
57
+ if oldHash .Equal (hash ) { // same hash, ignored
58
+ return nil
59
+ }
60
+ if len (data ) == 0 {
61
+ return fmt .Errorf ("can't download MMDB database file: no data" )
62
+ }
63
+
51
64
instance , err := maxminddb .FromBytes (data )
52
65
if err != nil {
53
66
return fmt .Errorf ("invalid MMDB database file: %s" , err )
54
67
}
55
68
_ = instance .Close ()
56
69
70
+ defer mmdb .ReloadIP ()
57
71
mmdb .IPInstance ().Reader .Close () // mmdb is loaded with mmap, so it needs to be closed before overwriting the file
58
- if err = saveFile ( data , C . Path . MMDB () ); err != nil {
72
+ if err = vehicle . Write ( data ); err != nil {
59
73
return fmt .Errorf ("can't save MMDB database file: %w" , err )
60
74
}
61
75
return nil
62
76
}
63
77
64
78
func UpdateASN () (err error ) {
65
- defer mmdb .ReloadASN ()
66
- data , err := downloadForBytes (geodata .ASNUrl ())
79
+ vehicle := resource .NewHTTPVehicle (geodata .ASNUrl (), C .Path .ASN (), "" , nil , defaultHttpTimeout )
80
+ var oldHash P.HashType
81
+ if buf , err := os .ReadFile (vehicle .Path ()); err == nil {
82
+ oldHash = P .MakeHash (buf )
83
+ }
84
+ data , hash , err := vehicle .Read (context .Background (), oldHash )
67
85
if err != nil {
68
86
return fmt .Errorf ("can't download ASN database file: %w" , err )
69
87
}
88
+ if oldHash .Equal (hash ) { // same hash, ignored
89
+ return nil
90
+ }
91
+ if len (data ) == 0 {
92
+ return fmt .Errorf ("can't download ASN database file: no data" )
93
+ }
70
94
71
95
instance , err := maxminddb .FromBytes (data )
72
96
if err != nil {
73
97
return fmt .Errorf ("invalid ASN database file: %s" , err )
74
98
}
75
99
_ = instance .Close ()
76
100
101
+ defer mmdb .ReloadASN ()
77
102
mmdb .ASNInstance ().Reader .Close () // mmdb is loaded with mmap, so it needs to be closed before overwriting the file
78
- if err = saveFile ( data , C . Path . ASN () ); err != nil {
103
+ if err = vehicle . Write ( data ); err != nil {
79
104
return fmt .Errorf ("can't save ASN database file: %w" , err )
80
105
}
81
106
return nil
82
107
}
83
108
84
109
func UpdateGeoIp () (err error ) {
85
- defer geodata .ClearGeoIPCache ()
86
110
geoLoader , err := geodata .GetGeoDataLoader ("standard" )
87
- data , err := downloadForBytes (geodata .GeoIpUrl ())
111
+
112
+ vehicle := resource .NewHTTPVehicle (geodata .GeoIpUrl (), C .Path .GeoIP (), "" , nil , defaultHttpTimeout )
113
+ var oldHash P.HashType
114
+ if buf , err := os .ReadFile (vehicle .Path ()); err == nil {
115
+ oldHash = P .MakeHash (buf )
116
+ }
117
+ data , hash , err := vehicle .Read (context .Background (), oldHash )
88
118
if err != nil {
89
119
return fmt .Errorf ("can't download GeoIP database file: %w" , err )
90
120
}
121
+ if oldHash .Equal (hash ) { // same hash, ignored
122
+ return nil
123
+ }
124
+ if len (data ) == 0 {
125
+ return fmt .Errorf ("can't download GeoIP database file: no data" )
126
+ }
127
+
91
128
if _ , err = geoLoader .LoadIPByBytes (data , "cn" ); err != nil {
92
129
return fmt .Errorf ("invalid GeoIP database file: %s" , err )
93
130
}
94
- if err = saveFile (data , C .Path .GeoIP ()); err != nil {
131
+
132
+ defer geodata .ClearGeoIPCache ()
133
+ if err = vehicle .Write (data ); err != nil {
95
134
return fmt .Errorf ("can't save GeoIP database file: %w" , err )
96
135
}
97
136
return nil
98
137
}
99
138
100
139
func UpdateGeoSite () (err error ) {
101
- defer geodata .ClearGeoSiteCache ()
102
140
geoLoader , err := geodata .GetGeoDataLoader ("standard" )
103
- data , err := downloadForBytes (geodata .GeoSiteUrl ())
141
+
142
+ vehicle := resource .NewHTTPVehicle (geodata .GeoSiteUrl (), C .Path .GeoSite (), "" , nil , defaultHttpTimeout )
143
+ var oldHash P.HashType
144
+ if buf , err := os .ReadFile (vehicle .Path ()); err == nil {
145
+ oldHash = P .MakeHash (buf )
146
+ }
147
+ data , hash , err := vehicle .Read (context .Background (), oldHash )
104
148
if err != nil {
105
149
return fmt .Errorf ("can't download GeoSite database file: %w" , err )
106
150
}
151
+ if oldHash .Equal (hash ) { // same hash, ignored
152
+ return nil
153
+ }
154
+ if len (data ) == 0 {
155
+ return fmt .Errorf ("can't download GeoSite database file: no data" )
156
+ }
107
157
108
158
if _ , err = geoLoader .LoadSiteByBytes (data , "cn" ); err != nil {
109
159
return fmt .Errorf ("invalid GeoSite database file: %s" , err )
110
160
}
111
161
112
- if err = saveFile (data , C .Path .GeoSite ()); err != nil {
162
+ defer geodata .ClearGeoSiteCache ()
163
+ if err = vehicle .Write (data ); err != nil {
113
164
return fmt .Errorf ("can't save GeoSite database file: %w" , err )
114
165
}
115
166
return nil
0 commit comments