|
|
@ -163,12 +163,28 @@ public class VaaHttpUtil { |
|
|
logger.info("录音文件下载完成: {}, 大小: {} bytes ({} MB)", |
|
|
logger.info("录音文件下载完成: {}, 大小: {} bytes ({} MB)", |
|
|
savePath, totalBytes, totalBytes / 1024 / 1024); |
|
|
savePath, totalBytes, totalBytes / 1024 / 1024); |
|
|
|
|
|
|
|
|
// 完整性校验:如果服务器返回了Content-Length,校验实际下载大小
|
|
|
// 完整性校验
|
|
|
if (expectedSize > 0 && totalBytes != expectedSize) { |
|
|
if (expectedSize > 0 && totalBytes != expectedSize) { |
|
|
saveFile.delete(); |
|
|
saveFile.delete(); |
|
|
throw new RuntimeException(String.format( |
|
|
throw new RuntimeException(String.format( |
|
|
"文件下载不完整: 期望 %d bytes, 实际 %d bytes", expectedSize, totalBytes)); |
|
|
"文件下载不完整: 期望 %d bytes, 实际 %d bytes", expectedSize, totalBytes)); |
|
|
} |
|
|
} |
|
|
|
|
|
// 录音文件至少应有1KB,过小说明下载异常
|
|
|
|
|
|
if (totalBytes < 1024) { |
|
|
|
|
|
saveFile.delete(); |
|
|
|
|
|
throw new RuntimeException(String.format( |
|
|
|
|
|
"文件过小,可能下载异常: 仅 %d bytes", totalBytes)); |
|
|
|
|
|
} |
|
|
|
|
|
// 校验文件头,确保不是HTML错误页面
|
|
|
|
|
|
byte[] header = new byte[(int) Math.min(totalBytes, 16)]; |
|
|
|
|
|
try (java.io.RandomAccessFile raf = new java.io.RandomAccessFile(saveFile, "r")) { |
|
|
|
|
|
raf.readFully(header); |
|
|
|
|
|
} |
|
|
|
|
|
String headerStr = new String(header, "ASCII").trim().toLowerCase(); |
|
|
|
|
|
if (headerStr.startsWith("<!doctype") || headerStr.startsWith("<html")) { |
|
|
|
|
|
saveFile.delete(); |
|
|
|
|
|
throw new RuntimeException("下载内容为HTML页面,非音频文件"); |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
throw new RuntimeException("文件下载失败,HTTP状态码: " + responseCode); |
|
|
throw new RuntimeException("文件下载失败,HTTP状态码: " + responseCode); |
|
|
} |
|
|
} |
|
|
|