Unbreak file serve ranges
This commit is contained in:
@@ -46,10 +46,11 @@ public class FileServeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Response serveFile(FileInfo fileInfo, String range) {
|
public Response serveFile(FileInfo fileInfo, String range) {
|
||||||
|
FileChannel channel = null;
|
||||||
try {
|
try {
|
||||||
Path path = Paths.get(fileApiConfiguration.directory(),
|
Path path = Paths.get(fileApiConfiguration.directory(),
|
||||||
URLDecoder.decode(fileInfo.directUrl, StandardCharsets.UTF_8));
|
URLDecoder.decode(fileInfo.directUrl, StandardCharsets.UTF_8));
|
||||||
FileChannel channel = FileChannel.open(path);
|
channel = FileChannel.open(path);
|
||||||
ResponseBuilder response;
|
ResponseBuilder response;
|
||||||
long fileSize = channel.size();
|
long fileSize = channel.size();
|
||||||
if (range != null) {
|
if (range != null) {
|
||||||
@@ -64,13 +65,15 @@ public class FileServeService {
|
|||||||
rangeEnd = Long.parseLong(rangeSplitted[1]);
|
rangeEnd = Long.parseLong(rangeSplitted[1]);
|
||||||
}
|
}
|
||||||
if (rangeEnd + 1 > fileSize) {
|
if (rangeEnd + 1 > fileSize) {
|
||||||
|
channel.close();
|
||||||
return Response.status(
|
return Response.status(
|
||||||
Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
|
Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();
|
||||||
}
|
}
|
||||||
InputStream is = Channels.newInputStream(channel);
|
|
||||||
is.skip(rangeStart);
|
|
||||||
response = Response.ok(path.toFile());
|
response = Response.ok(path.toFile());
|
||||||
response.entity(is.readNBytes((int) (rangeEnd + 1 - rangeStart)));
|
response.entity(new FileServeInputStream(Channels.newInputStream(channel),
|
||||||
|
rangeStart, rangeEnd));
|
||||||
|
|
||||||
response.header("Content-Length",
|
response.header("Content-Length",
|
||||||
Long.toString(rangeEnd + 1 - rangeStart));
|
Long.toString(rangeEnd + 1 - rangeStart));
|
||||||
response.status(Response.Status.PARTIAL_CONTENT);
|
response.status(Response.Status.PARTIAL_CONTENT);
|
||||||
@@ -79,6 +82,7 @@ public class FileServeService {
|
|||||||
} else {
|
} else {
|
||||||
response = Response.ok(path.toFile());
|
response = Response.ok(path.toFile());
|
||||||
response.header("Content-Length", Long.toString(fileSize));
|
response.header("Content-Length", Long.toString(fileSize));
|
||||||
|
channel.close();
|
||||||
}
|
}
|
||||||
response.header("Accept-Ranges", "bytes");
|
response.header("Accept-Ranges", "bytes");
|
||||||
response.header("Content-Disposition",
|
response.header("Content-Disposition",
|
||||||
@@ -89,8 +93,52 @@ public class FileServeService {
|
|||||||
}
|
}
|
||||||
return response.build();
|
return response.build();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
try {
|
||||||
|
channel.close();
|
||||||
|
} catch (Exception ignored) {}
|
||||||
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FileServeInputStream extends InputStream {
|
||||||
|
private InputStream is;
|
||||||
|
private long remaining;
|
||||||
|
|
||||||
|
public FileServeInputStream(InputStream is, long startRange, long endRange) throws IOException {
|
||||||
|
this.is = is;
|
||||||
|
try {
|
||||||
|
this.is.skip(startRange);
|
||||||
|
} catch (IOException e) {
|
||||||
|
try {
|
||||||
|
this.is.close();
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
this.remaining = endRange + 1 - startRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] buffer) throws IOException {
|
||||||
|
if (this.remaining == 0) {
|
||||||
|
this.is.close();
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
int read = this.is.read(buffer, 0, (int) Math.min(buffer.length, this.remaining));
|
||||||
|
this.remaining -= read;
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (this.remaining > 0) {
|
||||||
|
this.remaining--;
|
||||||
|
return this.is.read();
|
||||||
|
} else {
|
||||||
|
this.is.close();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user