YelinCui | 196bd69 | 2025-06-05 22:18:17 +0800 | [diff] [blame] | 1 | package com.example.myproject.controller; |
| 2 | |
| 3 | import cn.hutool.core.util.HexUtil; |
| 4 | |
| 5 | import com.example.myproject.dto.param.AnnounceRequest; |
| 6 | //import com.example.myproject.service.AnnounceService; |
| 7 | //import com.example.myproject.utils.BinaryFieldUtil; |
| 8 | import com.turn.ttorrent.bcodec.BEncoder; |
| 9 | //import com.example.myproject.utils.IPUtils; |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | import javax.servlet.http.HttpServletRequest; |
| 15 | import lombok.RequiredArgsConstructor; |
| 16 | import lombok.extern.slf4j.Slf4j; |
| 17 | import org.apache.commons.lang3.StringUtils; |
| 18 | import org.springframework.http.ResponseEntity; |
| 19 | import org.springframework.web.bind.annotation.*; |
| 20 | import org.springframework.web.client.RestTemplate; |
| 21 | |
| 22 | import java.nio.ByteBuffer; |
| 23 | import java.util.List; |
| 24 | import java.util.Map; |
| 25 | import java.util.Optional; |
| 26 | |
| 27 | @Slf4j |
| 28 | @RestController |
| 29 | @RequiredArgsConstructor |
| 30 | public class TrackerController { |
| 31 | |
| 32 | // private final AnnounceService announceService; |
| 33 | |
| 34 | private final RestTemplate restTemplate = new RestTemplate(); |
| 35 | |
| 36 | @GetMapping("/announce") |
| 37 | public ResponseEntity<byte[]> announce(HttpServletRequest request, |
| 38 | @ModelAttribute AnnounceRequest announceRequest, |
| 39 | @RequestHeader(name = "User-Agent") String ua, |
| 40 | @RequestHeader(name = "want-digest", required = false) String wantDigest) { |
| 41 | |
| 42 | // 1. 获取请求参数原始字符串(方便解析peerId、infoHash等) |
| 43 | String queryStrings = request.getQueryString(); |
| 44 | log.info("收到announce汇报:" + queryStrings); |
| 45 | //收到announce汇报:passkey=1&info_hash=%c8%8e%8ak8%09%97%1b%ab4%3a%a2%c3%bf%c3%22%05%f2j%d1&peer_id=-qB453A-9nl.HBf73dry&port=62128&uploaded=0&downloaded=0&left=1711543&corrupt=0&key=A0B2541D&event=started&numwant=200&compact=1&no_peer_id=1&supportcrypto=1&redundant=0 |
| 46 | // |
| 47 | // 2. 获取客户端IP |
| 48 | // 3. 提取peerId和infoHash(二进制字段) |
| 49 | // byte[] peerId = BinaryFieldUtil.matchPeerId(queryStrings); |
| 50 | // String peerIdHex = HexUtil.encodeHexStr(peerId); |
| 51 | // byte[] infoHash = BinaryFieldUtil.matchInfoHash(queryStrings); |
| 52 | |
| 53 | // log.info("peerid:" + peerId); |
| 54 | // log.info("infohash" + infoHash); |
| 55 | |
| 56 | // String ipAddr = IPUtils.getIpAddr(); |
| 57 | // |
| 58 | // |
| 59 | // |
| 60 | // // 4. 设置AnnounceRequest其他字段 |
| 61 | // announceRequest.setSeeder(announceRequest.getLeft() != null && announceRequest.getLeft().equals(0L)); |
| 62 | // announceRequest.setInfoHash(infoHash); |
| 63 | // announceRequest.setPeerId(peerId); |
| 64 | // announceRequest.setPeerIdHex(peerIdHex); |
| 65 | // announceRequest.setRemoteAddr(ipAddr); |
| 66 | // announceRequest.setWantDigest(wantDigest); |
| 67 | // announceRequest.setUserAgent(ua); |
| 68 | |
| 69 | // // 5. 先调用业务层处理,比如记录用户状态 |
| 70 | // announceService.announce(announceRequest); |
| 71 | |
| 72 | // 6. 转发请求到真正tracker(6969端口) |
| 73 | |
| 74 | // 构造转发URL |
| 75 | String trackerUrl = "http://localhost:6969/announce" + (queryStrings != null ? "?" + queryStrings : ""); |
| 76 | |
| 77 | // 使用RestTemplate发起GET请求,直接获取二进制响应(bencode) |
| 78 | ResponseEntity<byte[]> trackerResponse = restTemplate.getForEntity(trackerUrl, byte[].class); |
| 79 | |
| 80 | // 7. 直接将tracker返回的二进制数据,作为响应返回给客户端 |
| 81 | return ResponseEntity.ok() |
| 82 | .header("Content-Type", "text/plain") // bencode通常用text/plain,或者 application/x-bittorrent |
| 83 | .body(trackerResponse.getBody()); |
| 84 | |
| 85 | } |
| 86 | } |
| 87 | |