package net.geedge.api.controller; import cn.hutool.core.codec.Base32Codec; import jakarta.servlet.http.HttpServletResponse; import net.geedge.api.entity.EnvApiYml; import net.geedge.api.util.AdbUtil; import net.geedge.common.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; @RestController @RequestMapping("/api/v1/env") public class APIController { private final AdbUtil adbUtil; @Autowired public APIController(EnvApiYml envApiYml) { this.adbUtil = AdbUtil.getInstance(envApiYml.getAdb()); } @GetMapping("/status") public R status() { return R.ok(adbUtil.status()); } @PostMapping("/file") public R push(@RequestParam(value = "file") MultipartFile file, @RequestParam String path) throws IOException { File tempFile = null; try { tempFile = T.FileUtil.file(Constant.TEMP_PATH, file.getOriginalFilename()); file.transferTo(tempFile); AdbUtil.CommandResult result = adbUtil.push(tempFile.getAbsolutePath(), path); if (0 != result.exitCode()) { return R.error(result.output()); } } finally { T.FileUtil.del(tempFile); } return R.ok(); } @GetMapping("/file/{fileId}") public void pull(@PathVariable String fileId, HttpServletResponse response) throws IOException { byte[] decode = Base32Codec.Base32Decoder.DECODER.decode(fileId); String filePath = T.StrUtil.str(decode, T.CharsetUtil.CHARSET_UTF_8); String fileName = T.FileUtil.getName(filePath); File tempFile = T.FileUtil.file(Constant.TEMP_PATH, fileName); try { AdbUtil.CommandResult result = adbUtil.pull(filePath, tempFile.getAbsolutePath()); if (0 != result.exitCode()) { throw new APIException(result.output()); } if (T.FileUtil.isDirectory(tempFile)) { File zip = T.ZipUtil.zip(tempFile); try { T.ResponseUtil.downloadFile(response, zip.getName(), T.FileUtil.readBytes(zip)); } finally { T.FileUtil.del(zip); } } else { T.ResponseUtil.downloadFile(response, fileName, T.FileUtil.readBytes(tempFile)); } } finally { T.FileUtil.del(tempFile); } } @GetMapping("/file") public R listDir(@RequestParam(defaultValue = "/") String path) { List listDir = adbUtil.listDir(path); Map data = T.MapUtil.builder() .put("path", path) .put("records", listDir) .build(); return R.ok(data); } @GetMapping("/app") public R listApp(@RequestParam(required = false) String arg) { return R.ok().putData("records", adbUtil.listApp(arg)); } @PostMapping("/app") public R install(@RequestParam(value = "file", required = false) MultipartFile file, @RequestParam(required = false) String path) throws IOException { if (file != null) { File tempFile = null; try { tempFile = T.FileUtil.file(Constant.TEMP_PATH, file.getOriginalFilename()); file.transferTo(tempFile); AdbUtil.CommandResult result = adbUtil.install(tempFile.getAbsolutePath(), true, true); if (0 != result.exitCode()) { throw new APIException(result.output()); } return R.ok(); } finally { T.FileUtil.del(tempFile); } } if (T.StrUtil.isNotEmpty(path)) { AdbUtil.CommandResult result = adbUtil.install(path, true, true); if (0 != result.exitCode()) { throw new APIException(result.output()); } return R.ok(); } return R.error(RCode.BAD_REQUEST); } @DeleteMapping("/app") public R uninstall(@RequestParam String packageName) { AdbUtil.CommandResult result = adbUtil.uninstall(packageName); if (0 != result.exitCode()) { throw new APIException(result.output()); } return R.ok(); } @GetMapping("/pcap") public R listTcpdump() { return R.ok().putData("records", adbUtil.listTcpdump()); } @PostMapping("/pcap") public R startTcpdump(@RequestParam(required = false, defaultValue = "") String packageName) { AdbUtil.CommandResult result = adbUtil.startTcpdump(packageName); if (0 != result.exitCode()) { throw new APIException("exec tcpdump error"); } return R.ok().putData("id", result.output()); } @DeleteMapping("/pcap") public synchronized void stopTcpdump(@RequestParam String id, @RequestParam(required = false, defaultValue = "false") Boolean returnFile, HttpServletResponse response) throws IOException { AdbUtil.CommandResult result = adbUtil.stopTcpdump(id); if (0 != result.exitCode()) { throw new APIException(result.output()); } String filePath = result.output(); try { if (returnFile) { // response pcap file File tempFile = T.FileUtil.file(Constant.TEMP_PATH, id + ".pcap"); try { if (T.StrUtil.isEmpty(filePath)) { throw new APIException(RCode.NOT_EXISTS); } AdbUtil.CommandResult pulled = adbUtil.pull(filePath, tempFile.getAbsolutePath()); if (0 != pulled.exitCode()) { throw new APIException(pulled.output()); } T.ResponseUtil.downloadFile(response, tempFile.getName(), T.FileUtil.readBytes(tempFile)); } finally { T.FileUtil.del(tempFile); } } else { // response taskid response.getWriter().write(T.JSONUtil.toJsonStr(R.ok().putData("id", id))); } } finally { if (T.StrUtil.isNotEmpty(filePath)) { // remove pcap file adbUtil.execShellCommand(String.format("shell rm -rf %s", filePath)); } } } @PostMapping("/shell") public R execShellCmd(@RequestBody Map requestBody) { String cmd = T.MapUtil.getStr(requestBody, "cmd", ""); if (T.StrUtil.isEmpty(cmd)) { return R.error(RCode.BAD_REQUEST); } Integer timeout = T.MapUtil.getInt(requestBody, "timeout", 10); return R.ok().putData("result", adbUtil.execShellCommand(cmd, timeout)); } }