blob: 174942145f91ee8fe0745acf9aa779aab65660a4 [file] [log] [blame]
root59a69f82025-06-05 08:35:22 +00001package tracker;
2
3import java.io.InputStream;
4import java.io.OutputStream;
5import java.net.HttpURLConnection;
TRM-coding87c24972025-06-07 14:05:29 +08006import java.net.InetSocketAddress;
7import java.net.SocketAddress;
root59a69f82025-06-05 08:35:22 +00008import java.net.URL;
TRM-codingd5de51e2025-06-08 03:27:01 +08009import tracker.Tracker;
root59a69f82025-06-05 08:35:22 +000010import org.simpleframework.http.Request;
11import org.simpleframework.http.Response;
12import org.simpleframework.http.core.Container;
13
14/**
15 * 拦截 announce 请求,打印参数后转发给真实 Tracker。
16 */
17public class DataCaptureProxy implements Container {
18
19 private final String trackerHost;
20 private final int trackerPort;
TRM-codingcdfe5482025-06-06 17:31:01 +080021 private final Tracker tracker;
root59a69f82025-06-05 08:35:22 +000022
23 public DataCaptureProxy(String trackerHost, int trackerPort) {
24 this.trackerHost = trackerHost;
25 this.trackerPort = trackerPort;
TRM-coding87c24972025-06-07 14:05:29 +080026 this.tracker = new Tracker(); // 初始化 Tracker 实例
root59a69f82025-06-05 08:35:22 +000027 }
28
29 @Override
30 public void handle(Request req, Response resp) {
31 try {
32 // 提取并打印关键参数
TRM-coding87c24972025-06-07 14:05:29 +080033 String infoHash = req.getParameter("info_hash");
34 String uploaded = req.getParameter("uploaded");
35 String downloaded = req.getParameter("downloaded");
36 String passkey = req.getParameter("passkey");
TRM-codingd5de51e2025-06-08 03:27:01 +080037 String port = req.getParameter("port"); // qBittorrent 服务端端口
TRM-coding87c24972025-06-07 14:05:29 +080038
TRM-codingd5de51e2025-06-08 03:27:01 +080039 // 获取客户端IP地址和端口
TRM-coding87c24972025-06-07 14:05:29 +080040 String clientIp;
TRM-codingd5de51e2025-06-08 03:27:01 +080041 int clientPort = -1;
TRM-coding87c24972025-06-07 14:05:29 +080042 // 直接从 TCP 连接(socket 源地址)中读取
43 SocketAddress socketAddress = req.getClientAddress();
44 if (socketAddress instanceof InetSocketAddress) {
TRM-codingd5de51e2025-06-08 03:27:01 +080045 InetSocketAddress inetSocketAddress = (InetSocketAddress) socketAddress;
46 clientIp = inetSocketAddress.getAddress().getHostAddress();
47 clientPort = inetSocketAddress.getPort();
TRM-coding87c24972025-06-07 14:05:29 +080048 } else {
49 // 兜底写法,将整个 SocketAddress 转为字符串
50 clientIp = socketAddress.toString();
51 }
52
root59a69f82025-06-05 08:35:22 +000053 System.out.println(
54 "Captured announce → info_hash=" + infoHash +
55 ", uploaded=" + uploaded +
56 ", downloaded=" + downloaded +
TRM-coding87c24972025-06-07 14:05:29 +080057 ", passkey=" + passkey +
TRM-codingd5de51e2025-06-08 03:27:01 +080058 ", client_ip=" + clientIp +
59 ", client_port=" + clientPort +
60 ", qbt_service_port=" + port
root59a69f82025-06-05 08:35:22 +000061 );
62
TRM-coding87c24972025-06-07 14:05:29 +080063 // 调用 Tracker 方法更新上传和下载数据
TRM-codingd5de51e2025-06-08 03:27:01 +080064 if (passkey != null && !passkey.isEmpty() && infoHash != null && !infoHash.isEmpty()) {
TRM-codingcdfe5482025-06-06 17:31:01 +080065 try {
66 if (uploaded != null && !uploaded.isEmpty()) {
67 int uploadValue = Integer.parseInt(uploaded);
68 if (uploadValue > 0) {
TRM-coding508b31f2025-06-09 02:07:14 +080069 try {
70 tracker.AddUpLoad(passkey, uploadValue, infoHash);
71 } catch (javax.persistence.NoResultException e) {
72 System.out.println("Skipping upload update: info_hash not found in database - " + infoHash);
73 }
TRM-codingcdfe5482025-06-06 17:31:01 +080074 }
75 }
76
77 if (downloaded != null && !downloaded.isEmpty()) {
78 int downloadValue = Integer.parseInt(downloaded);
79 if (downloadValue > 0) {
TRM-coding508b31f2025-06-09 02:07:14 +080080 try {
81 tracker.AddDownload(passkey, downloadValue, infoHash);
82 } catch (javax.persistence.NoResultException e) {
83 System.out.println("Skipping download update: info_hash not found in database - " + infoHash);
84 }
TRM-codingcdfe5482025-06-06 17:31:01 +080085 }
86 }
87 } catch (NumberFormatException e) {
88 System.err.println("Error parsing upload/download values: " + e.getMessage());
89 }
90 }
91
root59a69f82025-06-05 08:35:22 +000092 // 构造转发 URL
TRM-coding87c24972025-06-07 14:05:29 +080093 String path = req.getPath().getPath();
root59a69f82025-06-05 08:35:22 +000094 String query = req.getQuery().toString();
95 String targetUrl = "http://" + trackerHost + ":" + trackerPort
96 + path + "?" + query;
97
98 HttpURLConnection connection =
99 (HttpURLConnection) new URL(targetUrl).openConnection();
100 connection.setRequestMethod("GET");
101
102 // 转发响应码和类型
103 resp.setCode(connection.getResponseCode());
104 String ct = connection.getContentType();
105 if (ct != null) resp.setValue("Content-Type", ct);
106
107 // 转发响应体
108 try (InputStream in = connection.getInputStream();
109 OutputStream out = resp.getOutputStream()) {
110 byte[] buf = new byte[8192];
111 int len;
112 while ((len = in.read(buf)) != -1) {
113 out.write(buf, 0, len);
114 }
115 }
116
117 } catch (Exception e) {
118 try {
119 resp.setCode(500);
120 resp.close();
121 } catch (Exception ignore) {}
122 e.printStackTrace();
123 }
124 }
125}