| package com.pt.controller; |
| |
| import com.pt.service.TorrentMetaService; |
| import com.pt.service.TrackerService; |
| import jakarta.servlet.http.HttpServletRequest; |
| import jakarta.servlet.http.HttpServletResponse; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.web.bind.annotation.*; |
| |
| import java.io.FileInputStream; |
| import java.io.IOException; |
| import java.net.URLDecoder; |
| import java.nio.charset.StandardCharsets; |
| import java.security.MessageDigest; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| @RestController |
| @RequestMapping("/api/tracker") |
| @CrossOrigin(origins = "*") |
| public class TrackerController { |
| |
| @Autowired |
| private TrackerService trackerService; |
| |
| @Autowired |
| private TorrentMetaService torrentMetaService; |
| |
| // tracker相应bt客户端的announce请求 |
| @GetMapping("/announce") |
| public void announce( |
| @RequestParam(value = "passkey", required = false) String passkey, |
| @RequestParam(value = "info_hash") String encodedInfoHash, |
| @RequestParam(value = "peer_id") String encodedPeerId, |
| @RequestParam(value = "port") int port, |
| @RequestParam(value = "uploaded") long uploaded, |
| @RequestParam(value = "downloaded") long downloaded, |
| @RequestParam(value = "left") long left, |
| @RequestParam(value = "event", defaultValue = "") String event, |
| @RequestParam(value = "compact", defaultValue = "1") int compact, |
| @RequestParam(value = "numwant", defaultValue = "50") int numwant, |
| HttpServletRequest request, |
| HttpServletResponse response |
| ) throws IOException { |
| try { |
| |
| System.out.println("TrackerController------------------------announce"); |
| // 解码 info_hash 和 peer_id(从URL编码的字符串转为字节数组) |
| System.out.println("TrackerController------------------------announce: info_hash=" + encodedInfoHash + ", peer_id=" + encodedPeerId); |
| String decodedInfoHash = URLDecoder.decode(encodedInfoHash, StandardCharsets.ISO_8859_1); |
| String decodedPeerId = URLDecoder.decode(encodedPeerId, StandardCharsets.ISO_8859_1); |
| |
| // 转换为字节数组 |
| byte[] infoHashBytes = decodedInfoHash.getBytes(StandardCharsets.ISO_8859_1); |
| byte[] peerIdBytes = decodedPeerId.getBytes(StandardCharsets.ISO_8859_1); |
| |
| // 验证 info_hash 长度 |
| // if (infoHashBytes.length != 20) { |
| // throw new IllegalArgumentException("Invalid info_hash length"); |
| // } |
| |
| // 获取客户端IP |
| String ip = request.getRemoteAddr(); |
| System.out.println("Client IP: " + ip); |
| |
| // 将参数封装为 Map 传给服务层 |
| Map<String, Object> params = new HashMap<>(); |
| params.put("info_hash", decodedInfoHash); |
| params.put("peer_id", decodedPeerId); |
| params.put("port", port); |
| params.put("uploaded", uploaded); |
| params.put("downloaded", downloaded); |
| params.put("left", left); |
| params.put("event", event); |
| params.put("compact", compact); |
| params.put("numwant", numwant); |
| params.put("ip", ip); |
| params.put("passkey", passkey); |
| |
| byte[] bencodedResponse = trackerService.handleAnnounce(params, ip, event); |
| response.setContentType("application/x-bittorrent"); |
| response.getOutputStream().write(bencodedResponse); |
| |
| } catch (IllegalArgumentException e) { |
| System.out.println("TrackerService-----------------------Error processing announce request111: " + e.getMessage()); |
| e.printStackTrace(); |
| String errorResponse = "d14:failure reason" + e.getMessage().length() + ":" + e.getMessage() + "e"; |
| response.setContentType("application/x-bittorrent"); |
| response.getOutputStream().write(errorResponse.getBytes(StandardCharsets.ISO_8859_1)); |
| } catch (Exception e) { |
| e.printStackTrace(); |
| System.out.println("TrackerService-----------------------Error processing announce request222: " + e.getMessage()); |
| String errorResponse = "d14:failure reason20:Internal server errore"; |
| response.setContentType("application/x-bittorrent"); |
| response.getOutputStream().write(errorResponse.getBytes(StandardCharsets.ISO_8859_1)); |
| } |
| } |
| |
| |
| } |
| |