diff --git a/GeoLite2-City/GeoLite2-City.mmdb b/GeoLite2-City/GeoLite2-City.mmdb deleted file mode 100644 index 247a5d57..00000000 Binary files a/GeoLite2-City/GeoLite2-City.mmdb and /dev/null differ diff --git a/pom.xml b/pom.xml index ab51fa87..321cfa1c 100644 --- a/pom.xml +++ b/pom.xml @@ -50,10 +50,20 @@ + + + org.lionsoul + ip2region + 2.7.0 + org.springframework.boot spring-boot-starter-quartz + + org.springframework.boot + spring-boot-starter-websocket + com.aliyun.oss diff --git a/src/main/java/cn/lihongjie/coal/ip/IpQueryService.java b/src/main/java/cn/lihongjie/coal/ip/IpQueryService.java index 39c57a27..83660bb6 100644 --- a/src/main/java/cn/lihongjie/coal/ip/IpQueryService.java +++ b/src/main/java/cn/lihongjie/coal/ip/IpQueryService.java @@ -1,29 +1,22 @@ package cn.lihongjie.coal.ip; import com.maxmind.geoip2.DatabaseReader; -import com.maxmind.geoip2.model.CityResponse; import jakarta.annotation.PostConstruct; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.compress.archivers.tar.TarArchiveEntry; -import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; -import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream; -import org.apache.commons.io.FileUtils; -import org.apache.commons.lang3.StringUtils; +import org.lionsoul.ip2region.xdb.Searcher; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.env.Environment; +import org.springframework.core.io.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.*; import java.net.InetAddress; -import java.net.URL; -import java.nio.file.Files; -import java.nio.file.Path; @Service @Slf4j @@ -37,84 +30,38 @@ class IpQueryService { private String geolite2DownloadUrl; private DatabaseReader reader; + @Value("classpath:ip/ip2region.xdb") + Resource dbFile; + private Searcher searcher; + + private static boolean isPrivateAddress(InetAddress inetAddress) { + byte[] addressBytes = inetAddress.getAddress(); + int byte1 = addressBytes[0] & 0xff; + int byte2 = addressBytes[1] & 0xff; + + return (byte1 == 10) || + (byte1 == 172 && (byte2 >= 16 && byte2 <= 31)) || + (byte1 == 192 && byte2 == 168); + } + + @SneakyThrows + public static void main(String[] args){ + System.out.println(isPrivateAddress(InetAddress.getByName("192.168.0.1"))); + } @SneakyThrows @PostConstruct public void init() { - log.info("开始初始化GeoLite2-City本地数据库"); - Path dbPath = Path.of("./GeoLite2-City/GeoLite2-City.mmdb"); - - Path dbDir = dbPath.getParent(); - if (Files.notExists(dbDir)) { - - Files.createDirectories(dbDir); + // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。 + try { + searcher = Searcher.newWithBuffer(dbFile.getContentAsByteArray()); + } catch (Exception e) { + log.warn("failed to new searcher with buffer", e); + return; } - - if (Files.exists(dbPath)) { - - log.info("发现默认数据库文件: {}", dbPath); - - } else if (StringUtils.isNotEmpty(environment.getProperty("geolite2.city.path"))) { - - dbPath = Path.of(environment.getProperty("geolite2.city.path")); - - log.info("发现环境变量数据库文件: {}", dbPath); - - } else { - - log.info("没有找到数据库文件, 下载数据库文件"); - - File downloadPath = dbPath.getParent().resolve("GeoLite2-City.tar.gz").toFile(); - FileUtils.copyURLToFile( - new URL(geolite2DownloadUrl), downloadPath, 10 * 1000, 30 * 1000); - - TarArchiveInputStream tarIn = - new TarArchiveInputStream( - new GzipCompressorInputStream( - new BufferedInputStream(new FileInputStream(downloadPath)))); - - TarArchiveEntry tarEntry = tarIn.getNextTarEntry(); - Path newDbFile = null; - // tarIn is a TarArchiveInputStream - while (tarEntry != null) { // create a file with the same name as the tarEntry - File destPath = dbDir.resolve(tarEntry.getName()).toFile(); - log.info(destPath.toString()); - - if (tarEntry.isDirectory()) { - destPath.mkdirs(); - } else { - destPath.createNewFile(); - if (destPath.getName().endsWith("mmdb")) { - newDbFile = destPath.toPath(); - } - // byte [] btoRead = new byte[(int)tarEntry.getSize()]; - byte[] btoRead = new byte[1024]; - // FileInputStream fin - // = new FileInputStream(destPath.getCanonicalPath()); - BufferedOutputStream bout = - new BufferedOutputStream(new FileOutputStream(destPath)); - int len = 0; - - while ((len = tarIn.read(btoRead)) != -1) { - bout.write(btoRead, 0, len); - } - - bout.close(); - btoRead = null; - } - tarEntry = tarIn.getNextTarEntry(); - } - tarIn.close(); - - if (newDbFile != null) { - - Files.move(newDbFile, dbPath); - } - } - - reader = new DatabaseReader.Builder(dbPath.toFile()).build(); + log.info("加载 ip2region.db 成功"); } @SneakyThrows @@ -122,14 +69,21 @@ class IpQueryService { if (reader != null) { InetAddress ipAddress = InetAddress.getByName(ipaddr); - boolean siteLocalAddress = ipAddress.isSiteLocalAddress(); - if (siteLocalAddress) { + if (ipAddress.isAnyLocalAddress()) { + return "服务器本机地址"; + } + if (ipAddress.isLoopbackAddress()) { + return "本地回环地址"; + } + if (isPrivateAddress(ipAddress)) { return "内网地址"; } + + try { - CityResponse city = reader.city(ipAddress); - return city.getCountry().getName() + city.getCity().getName(); + String search = searcher.search(ipaddr); + return search.replace("|0|", "").replace("|", ""); } catch (Exception e) { return ""; } diff --git a/src/main/resources/ip/ip2region.xdb b/src/main/resources/ip/ip2region.xdb new file mode 100644 index 00000000..c78b7928 Binary files /dev/null and b/src/main/resources/ip/ip2region.xdb differ