wuchimedes | 223bfab | 2025-04-04 17:16:05 +0800 | [diff] [blame] | 1 | package com.example.g8backend.controller; |
| 2 | |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 3 | import com.example.g8backend.dto.AnnounceRequestDTO; |
| 4 | import com.example.g8backend.dto.AnnounceResponseDTO; |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 5 | import com.example.g8backend.util.BencodeUtil; |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 6 | import jakarta.servlet.http.HttpServletRequest; |
22301071 | f1381f8 | 2025-06-06 21:32:34 +0800 | [diff] [blame] | 7 | import org.slf4j.Logger; |
| 8 | import org.slf4j.LoggerFactory; |
wuchimedes | 223bfab | 2025-04-04 17:16:05 +0800 | [diff] [blame] | 9 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | import org.springframework.http.ResponseEntity; |
wuchimedes | a0649c6 | 2025-04-05 15:53:39 +0800 | [diff] [blame] | 11 | import org.springframework.web.bind.annotation.*; |
wuchimedes | 223bfab | 2025-04-04 17:16:05 +0800 | [diff] [blame] | 12 | import com.example.g8backend.service.ITrackerService; |
| 13 | |
| 14 | @RestController |
wuchimedes | a0649c6 | 2025-04-05 15:53:39 +0800 | [diff] [blame] | 15 | @RequestMapping("/tracker") |
wuchimedes | 223bfab | 2025-04-04 17:16:05 +0800 | [diff] [blame] | 16 | public class TrackerController { |
| 17 | |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 18 | private static final Logger logger = LoggerFactory.getLogger(TrackerController.class); |
| 19 | |
wuchimedes | a0649c6 | 2025-04-05 15:53:39 +0800 | [diff] [blame] | 20 | @Autowired |
| 21 | private ITrackerService trackerService; |
| 22 | |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 23 | @GetMapping(value = "/announce/{passkey}", produces = "application/x-bittorrent") |
| 24 | public ResponseEntity<byte[]> getAnnouncements( |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 25 | HttpServletRequest request, |
| 26 | @RequestParam("info_hash") String infoHash, |
| 27 | @RequestParam("peer_id") String peerId, |
| 28 | @RequestParam("port") int port, |
| 29 | @RequestParam("uploaded") double uploaded, |
| 30 | @RequestParam("downloaded") double downloaded, |
| 31 | @RequestParam(value = "event", required = false) String event, |
| 32 | @RequestParam(value = "left", required = false) Double left, |
| 33 | @RequestParam(value = "compact", required = false) Integer compact, |
wuchimedes | a0649c6 | 2025-04-05 15:53:39 +0800 | [diff] [blame] | 34 | @PathVariable String passkey) { |
| 35 | |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 36 | logger.info("Announce request received: info_hash={}, peer_id={}, port={}, uploaded={}, downloaded={}, event={}, left={}, compact={}, passkey={}", |
| 37 | infoHash, peerId, port, uploaded, downloaded, event, left, compact, passkey); |
22301071 | f1381f8 | 2025-06-06 21:32:34 +0800 | [diff] [blame] | 38 | |
wuchimedes | aa4baa5 | 2025-06-08 17:39:53 +0800 | [diff] [blame^] | 39 | System.out.println("passkey: " + passkey); |
| 40 | System.out.println("info_hash: " + infoHash); |
| 41 | |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 42 | AnnounceRequestDTO requestDTO = new AnnounceRequestDTO(); |
| 43 | requestDTO.setPasskey(passkey); |
| 44 | requestDTO.setInfoHash(infoHash); |
| 45 | requestDTO.setPeerId(peerId); |
| 46 | requestDTO.setPort(port); |
| 47 | requestDTO.setUploaded(uploaded); |
| 48 | requestDTO.setDownloaded(downloaded); |
| 49 | requestDTO.setEvent(event); |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 50 | requestDTO.setLeft(left != null ? left : 0.0); |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 51 | requestDTO.setCompact(compact); |
| 52 | |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 53 | String ipAddress = extractClientIp(request); |
| 54 | requestDTO.setIp(ipAddress); |
22301071 | f1381f8 | 2025-06-06 21:32:34 +0800 | [diff] [blame] | 55 | |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 56 | AnnounceResponseDTO responseDTO = trackerService.handleAnnounce(requestDTO); |
| 57 | |
| 58 | byte[] bencoded = BencodeUtil.encodeAnnounceResponse(responseDTO); |
| 59 | return ResponseEntity |
| 60 | .ok() |
| 61 | .header("Content-Type", "application/x-bittorrent") |
| 62 | .body(bencoded); |
| 63 | } |
| 64 | |
| 65 | /** |
| 66 | * 提取客户端 IP,支持 X-Forwarded-For |
| 67 | */ |
| 68 | private String extractClientIp(HttpServletRequest request) { |
| 69 | String xfHeader = request.getHeader("X-Forwarded-For"); |
| 70 | if (xfHeader != null && !xfHeader.isEmpty()) { |
| 71 | return xfHeader.split(",")[0].trim(); |
wuchimedes | db9fe68 | 2025-04-22 19:24:11 +0800 | [diff] [blame] | 72 | } |
22301071 | 66504b7 | 2025-06-08 13:54:29 +0800 | [diff] [blame] | 73 | return request.getRemoteAddr(); |
wuchimedes | a0649c6 | 2025-04-05 15:53:39 +0800 | [diff] [blame] | 74 | } |
wuchimedes | 223bfab | 2025-04-04 17:16:05 +0800 | [diff] [blame] | 75 | } |