|
|
|
|
@ -60,6 +60,28 @@ public class FileController {
|
|
|
|
|
@GetMapping("stream/**") |
|
|
|
|
public void download(HttpServletRequest request, HttpServletResponse response) throws IOException { |
|
|
|
|
String filePath = request.getRequestURI().substring(12); |
|
|
|
|
String lower = filePath.toLowerCase(); |
|
|
|
|
String range = request.getHeader("Range"); |
|
|
|
|
if (StrUtil.isNotBlank(range) && range.startsWith("bytes=")) { |
|
|
|
|
try (var upstream = fileService.downloadResponse(filePath, range); |
|
|
|
|
InputStream is = upstream.bodyStream()) { |
|
|
|
|
String contentType = Optional.ofNullable(upstream.header("Content-Type")) |
|
|
|
|
.orElseGet(() -> guessContentType(lower)); |
|
|
|
|
response.setContentType(contentType); |
|
|
|
|
response.setHeader("Accept-Ranges", "bytes"); |
|
|
|
|
String contentRange = upstream.header("Content-Range"); |
|
|
|
|
if (StrUtil.isNotBlank(contentRange)) response.setHeader("Content-Range", contentRange); |
|
|
|
|
String contentLength = upstream.header("Content-Length"); |
|
|
|
|
if (StrUtil.isNotBlank(contentLength)) response.setHeader("Content-Length", contentLength); |
|
|
|
|
response.setStatus(upstream.getStatus()); |
|
|
|
|
IoUtil.copy(is, response.getOutputStream()); |
|
|
|
|
return; |
|
|
|
|
} catch (Exception e) { |
|
|
|
|
log.error("Range stream failed, filePath={}, range={}", filePath, range, e); |
|
|
|
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (filePath.toLowerCase().endsWith(".pdf")) { |
|
|
|
|
response.setContentType("application/pdf"); |
|
|
|
|
} else { |
|
|
|
|
@ -99,4 +121,11 @@ public class FileController {
|
|
|
|
|
return Result.success(JSONObject.of("html", WordUtil.convertHtml(is))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private String guessContentType(String lower) { |
|
|
|
|
if (lower.endsWith(".mp4")) return "video/mp4"; |
|
|
|
|
if (lower.endsWith(".webm")) return "video/webm"; |
|
|
|
|
if (lower.endsWith(".mp3")) return "audio/mpeg"; |
|
|
|
|
if (lower.endsWith(".wav")) return "audio/wav"; |
|
|
|
|
return "application/octet-stream"; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|