blob: cb66feb854f7ac5bbb4b8bdfc46f0edb17dcdfc4 [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-codingd5de51e2025-06-08 03:27:01 +080069 tracker.AddUpLoad(passkey, uploadValue, infoHash);
TRM-codingcdfe5482025-06-06 17:31:01 +080070 }
71 }
72
73 if (downloaded != null && !downloaded.isEmpty()) {
74 int downloadValue = Integer.parseInt(downloaded);
75 if (downloadValue > 0) {
TRM-codingd5de51e2025-06-08 03:27:01 +080076 tracker.AddDownload(passkey, downloadValue, infoHash);
TRM-codingcdfe5482025-06-06 17:31:01 +080077 }
78 }
79 } catch (NumberFormatException e) {
80 System.err.println("Error parsing upload/download values: " + e.getMessage());
81 }
82 }
83
root59a69f82025-06-05 08:35:22 +000084 // 构造转发 URL
TRM-coding87c24972025-06-07 14:05:29 +080085 String path = req.getPath().getPath();
root59a69f82025-06-05 08:35:22 +000086 String query = req.getQuery().toString();
87 String targetUrl = "http://" + trackerHost + ":" + trackerPort
88 + path + "?" + query;
89
90 HttpURLConnection connection =
91 (HttpURLConnection) new URL(targetUrl).openConnection();
92 connection.setRequestMethod("GET");
93
94 // 转发响应码和类型
95 resp.setCode(connection.getResponseCode());
96 String ct = connection.getContentType();
97 if (ct != null) resp.setValue("Content-Type", ct);
98
99 // 转发响应体
100 try (InputStream in = connection.getInputStream();
101 OutputStream out = resp.getOutputStream()) {
102 byte[] buf = new byte[8192];
103 int len;
104 while ((len = in.read(buf)) != -1) {
105 out.write(buf, 0, len);
106 }
107 }
108
109 } catch (Exception e) {
110 try {
111 resp.setCode(500);
112 resp.close();
113 } catch (Exception ignore) {}
114 e.printStackTrace();
115 }
116 }
117}