add torrent download (no test)

Change-Id: Ie6e91be0c3d982d38d75b8f175aeba5052c873a8
diff --git a/src/main/java/com/example/g8backend/controller/TorrentController.java b/src/main/java/com/example/g8backend/controller/TorrentController.java
index bec187e..5a8b473 100644
--- a/src/main/java/com/example/g8backend/controller/TorrentController.java
+++ b/src/main/java/com/example/g8backend/controller/TorrentController.java
@@ -1,19 +1,21 @@
 package com.example.g8backend.controller;
 
 import com.example.g8backend.entity.User;
+import com.example.g8backend.entity.Torrent;
 import com.example.g8backend.service.IUserService;
+import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.example.g8backend.service.ITorrentService;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
 @RestController
 @RequestMapping("/torrent")
@@ -43,4 +45,25 @@
         }
         return ResponseEntity.ok("种子上传成功");
     }
+
+    @GetMapping("/download/{torrentId}")
+    public void downloadTorrent(@PathVariable String torrentId, HttpServletResponse response) throws IOException {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        long userId = (long) authentication.getPrincipal();
+
+        User user = userService.getById(userId);
+        String passkey = user.getPasskey();
+        Torrent torrent = torrentService.findByTorrentId(Long.parseLong(torrentId));
+        File tempFile = torrentService.handleTorrentDownload(torrent, passkey);
+
+        response.setContentType("application/x-bittorrent");
+        response.setHeader("Content-Disposition", "attachment; filename=\"" + torrent.getTorrentName() + "\"");
+
+        try (InputStream inputStream = new FileInputStream(tempFile)) {
+            inputStream.transferTo(response.getOutputStream());
+        }
+        if (!tempFile.delete()) {
+            throw new IOException("Failed to delete temporary file: " + tempFile.getAbsolutePath());
+        }
+    }
 }
diff --git a/src/main/java/com/example/g8backend/controller/TrackerController.java b/src/main/java/com/example/g8backend/controller/TrackerController.java
index d6cc957..1511c76 100644
--- a/src/main/java/com/example/g8backend/controller/TrackerController.java
+++ b/src/main/java/com/example/g8backend/controller/TrackerController.java
@@ -16,7 +16,7 @@
     @Autowired
     private RedisTemplate<String, Object> redisTemplate;
 
-    @GetMapping("/announce/{passkey}}")
+    @GetMapping("/announce/{passkey}")
     public ResponseEntity<?> getAnnouncements(
             @RequestParam(name = "info_hash") String infoHash,
             @RequestParam(name = "peer_id") String peerId,
diff --git a/src/main/java/com/example/g8backend/service/ITorrentService.java b/src/main/java/com/example/g8backend/service/ITorrentService.java
index 5e48dc4..87622c8 100644
--- a/src/main/java/com/example/g8backend/service/ITorrentService.java
+++ b/src/main/java/com/example/g8backend/service/ITorrentService.java
@@ -8,6 +8,7 @@
 
 public interface ITorrentService extends IService<Torrent> {
     Torrent handleTorrentUpload(File file, Long userId, String passkey) throws IOException;
+    File handleTorrentDownload(Torrent torrent, String passkey) throws IOException;
     Torrent findByInfoHash(String infoHash);
     Torrent findByTorrentId(Long torrentId);
 }
diff --git a/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java
index 03185ba..8d9ae74 100644
--- a/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java
+++ b/src/main/java/com/example/g8backend/service/impl/TorrentServiceImpl.java
@@ -17,12 +17,12 @@
     @Resource
     private TorrentMapper torrentMapper;
 
+    String tracker = "http://127.0.0.1:8080/announce/";
+
     @Override
     public Torrent handleTorrentUpload(File file, Long userId, String passkey) throws IOException{
-        String tracker = "http://127.0.0.1:8080/announce/" + passkey;
-
         // 修改 announce 字段
-        byte[] modifiedBytes = TorrentUtil.injectTracker(file, tracker);
+        byte[] modifiedBytes = TorrentUtil.injectTracker(file, tracker + passkey);
 
         // 计算 info_hash
         String infoHash = TorrentUtil.getInfoHash(file);
@@ -56,6 +56,18 @@
     }
 
     @Override
+    public File handleTorrentDownload(Torrent torrent, String passkey) throws IOException {
+        File torrentFile = new File("uploaded-torrents/" + torrent.getTorrentName());
+        byte[] modifiedBytes = TorrentUtil.injectTracker(torrentFile, tracker + passkey);
+
+        File tempFile = File.createTempFile("user_torrent_", ".torrent");
+        try (FileOutputStream fos = new FileOutputStream(tempFile)) {
+            fos.write(modifiedBytes);
+        }
+        return tempFile;
+    }
+
+    @Override
     public Torrent findByInfoHash(String infoHash){
         return torrentMapper.getTorrentByInfoHash(infoHash);
     }