新增文件下载监控,当有新ip下载文件时推送消息

This commit is contained in:
chuzhongzai 2024-08-20 17:03:15 +08:00
parent 8dbfcb9a67
commit da9ab50613
5 changed files with 66 additions and 8 deletions

12
pom.xml
View File

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version> <version>3.3.2</version>
<relativePath/> <!-- lookup parent from repository --> <relativePath/> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.lion</groupId> <groupId>com.lion</groupId>
@ -62,6 +62,12 @@
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.15.3</version>
</dependency>
<dependency> <dependency>
<groupId>cn.hutool</groupId> <groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId> <artifactId>hutool-all</artifactId>
@ -76,7 +82,7 @@
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId> <artifactId>commons-compress</artifactId>
<version>1.25.0</version> <version>1.26.1</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -102,7 +108,7 @@
<buildArgs> <buildArgs>
<arg>--gc=G1</arg> <arg>--gc=G1</arg>
<arg>-H:+ReportExceptionStackTraces</arg> <arg>-H:+ReportExceptionStackTraces</arg>
<arg>--initialize-at-build-time=org.apache.commons.logging.LogFactory,org.apache.commons.logging.LogFactoryService</arg> <arg>--initialize-at-build-time=org.apache.commons.logging.LogFactory,org.apache.commons.logging.LogFactoryService,org.sqlite.util.ProcessRunner</arg>
</buildArgs> </buildArgs>
<metadataRepository> <metadataRepository>
<enabled>true</enabled> <enabled>true</enabled>

View File

@ -38,6 +38,7 @@ import org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
import org.springframework.beans.factory.support.RegisteredBean; import org.springframework.beans.factory.support.RegisteredBean;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
@ -201,8 +202,7 @@ public class MyBatisNativeConfiguration {
} else { } else {
result = (Class<?>) src; result = (Class<?>) src;
} }
} else if (src instanceof ParameterizedType) { } else if (src instanceof ParameterizedType parameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) src;
int index = (parameterizedType.getRawType() instanceof Class int index = (parameterizedType.getRawType() instanceof Class
&& Map.class.isAssignableFrom((Class<?>) parameterizedType.getRawType()) && Map.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())
&& parameterizedType.getActualTypeArguments().length > 1) ? 1 : 0; && parameterizedType.getActualTypeArguments().length > 1) ? 1 : 0;
@ -246,8 +246,11 @@ public class MyBatisNativeConfiguration {
Class<?> mapperInterface = getMapperInterface(beanDefinition); Class<?> mapperInterface = getMapperInterface(beanDefinition);
if (mapperInterface != null) { if (mapperInterface != null) {
// Exposes a generic type information to context for prevent early initializing // Exposes a generic type information to context for prevent early initializing
beanDefinition // Exposes a generic type information to context for prevent early initializing
.setTargetType(ResolvableType.forClassWithGenerics(beanDefinition.getBeanClass(), mapperInterface)); ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
constructorArgumentValues.addGenericArgumentValue(mapperInterface);
beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
beanDefinition.setTargetType(ResolvableType.forClassWithGenerics(beanDefinition.getBeanClass(), mapperInterface));
} }
} }
} }

View File

@ -38,6 +38,9 @@ public interface ShareFileMapper {
@Select("select * from share_file where sharer=#{userid}") @Select("select * from share_file where sharer=#{userid}")
ShareFile[] selectAllShareFileByUserid(int userid); ShareFile[] selectAllShareFileByUserid(int userid);
@Select("select count(*) from share_file_download_record where share_code=#{shareCode} and ip=#{ip}")
int isDownloadBefore(@Param("shareCode") String shareCode, @Param("ip") String ip);
@Update("update share_file set expire_time=#{expireTime}, available_count=#{availableCount}, total_count=#{totalCount} " + @Update("update share_file set expire_time=#{expireTime}, available_count=#{availableCount}, total_count=#{totalCount} " +
"where share_code = #{shareCode}") "where share_code = #{shareCode}")
void updateShareFile(ShareFile shareFile); void updateShareFile(ShareFile shareFile);

View File

@ -6,6 +6,7 @@ import com.lion.snss.interceptor.Interceptor;
import com.lion.snss.message.DynamicConfigMessage; import com.lion.snss.message.DynamicConfigMessage;
import com.lion.snss.pojo.ShareFile; import com.lion.snss.pojo.ShareFile;
import com.lion.snss.pojo.User; import com.lion.snss.pojo.User;
import com.lion.snss.util.CustomUtil;
import com.lion.snss.util.IoUtil; import com.lion.snss.util.IoUtil;
import com.lion.snss.util.Response; import com.lion.snss.util.Response;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@ -115,13 +116,20 @@ public class FileService {
} }
//判断文件是否存在 //判断文件是否存在
if(!new File(shareFile.getFilePath()).isFile()){ File file = new File(shareFile.getFilePath());
if(!file.isFile()){
try { try {
httpResponse.sendError(404, "File is not exist"); httpResponse.sendError(404, "File is not exist");
return; return;
} catch (IOException e) {throw new RuntimeException(e);} } catch (IOException e) {throw new RuntimeException(e);}
} }
//如果该文件被新ip下载通知进行tg推送
if(shareFileMapper.isDownloadBefore(shareCode, ip) == 0){
String message = "文件:" + file.getName() + "\n被新ip:" + ip + "下载\n归属地:" + CustomUtil.getLocationByIp(ip);
CustomUtil.notifyMe(message);
}
//ipAndShareCode为下载ip+shareCode如果包含的话则说明这个ip不是第一次下载这个文件了 //ipAndShareCode为下载ip+shareCode如果包含的话则说明这个ip不是第一次下载这个文件了
if(ipAndShareCode.containsKey(ip+shareCode)) { if(ipAndShareCode.containsKey(ip+shareCode)) {
long before = ipAndShareCode.get(ip+shareCode); long before = ipAndShareCode.get(ip+shareCode);

View File

@ -2,10 +2,18 @@ package com.lion.snss.util;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data; import lombok.Data;
import org.jsoup.Jsoup;
import org.jsoup.select.Elements;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.Charset;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -69,4 +77,34 @@ public class CustomUtil {
return size.get(); return size.get();
} }
public static void notifyMe(String message){
try (HttpClient httpClient = HttpClient.newHttpClient()) {
HttpRequest httpRequest = HttpRequest.newBuilder(URI.create("https://personal.lionwebsite.xyz/message2me?AuthCode=alone&message=" + URLEncoder.encode(message, Charset.defaultCharset()))).POST(HttpRequest.BodyPublishers.noBody()).build();
httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
} catch (IOException | InterruptedException e) {
System.out.println("发送消息:" + message + " 失败");
throw new RuntimeException(e);
}
}
public static String getLocationByIp(String ip){
String location;
try (HttpClient httpClient = HttpClient.newHttpClient()){
HttpRequest httpRequest = HttpRequest.newBuilder(URI.create("https://www.ip138.com/iplookup.php?ip=" + ip))
.headers("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0",
"Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8").GET().build();
String page = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()).body();
Elements tds = Jsoup.parse(page).select("body > div > div.container > div.content > div > div:nth-child(2) > div.group-left > div > div.bd > div.table-outer > div.table-box > table > tbody > tr > td");
if(tds.size() > 3)
location = tds.get(1).text().replace("中国", "") + " " + tds.get(3).text().trim();
else
location = tds.get(1).text();
}catch (Exception e){
System.out.println("获取ip地址信息失败: " + e.getMessage());
location = "unknown";
}
return location;
}
} }