pull/590/head
FongMi 10 months ago
parent c3491e1749
commit ad20e9a058
  1. 98
      app/src/main/java/com/fongmi/android/tv/server/process/Local.java

@ -4,13 +4,13 @@ import com.fongmi.android.tv.server.Nano;
import com.fongmi.android.tv.server.impl.Process;
import com.fongmi.android.tv.utils.FileUtil;
import com.github.catvod.utils.Path;
import com.google.common.net.HttpHeaders;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@ -97,64 +97,66 @@ public class Local implements Process {
return Nano.ok(info.toString());
}
private NanoHTTPD.Response getFile(Map<String, String> header, File file, String mime) throws Exception {
long startFrom = 0;
long endAt = -1;
String range = header.get("range");
if (range != null) {
if (range.startsWith("bytes=")) {
range = range.substring("bytes=".length());
int minus = range.indexOf('-');
try {
if (minus > 0) {
startFrom = Long.parseLong(range.substring(0, minus));
endAt = Long.parseLong(range.substring(minus + 1));
}
} catch (NumberFormatException ignored) {
}
private NanoHTTPD.Response getFile(Map<String, String> headers, File file, String mime) throws IOException {
if (mime == null) mime = "application/octet-stream";
long fileLen = file.length();
long startFrom = 0, endAt = fileLen - 1;
String range = headers.get("range");
if (range != null && range.startsWith("bytes=")) {
try {
String[] parts = range.substring(6).split("-", 2);
if (!parts[0].isEmpty()) startFrom = Long.parseLong(parts[0]);
if (parts.length > 1 && !parts[1].isEmpty()) endAt = Long.parseLong(parts[1]);
if (startFrom > endAt) startFrom = 0;
if (endAt >= fileLen) endAt = fileLen - 1;
} catch (NumberFormatException ignored) {
startFrom = 0;
endAt = fileLen - 1;
}
}
String ifRange = headers.get("if-range");
String ifNoneMatch = headers.get("if-none-match");
String etag = Integer.toHexString((file.getAbsolutePath() + file.lastModified() + fileLen).hashCode());
boolean ifRangeMatch = (ifRange == null || ifRange.equals(etag));
boolean ifNoneMatchHit = ifNoneMatch != null && ("*".equals(ifNoneMatch) || ifNoneMatch.equals(etag));
long contentLength;
NanoHTTPD.Response res;
long fileLen = file.length();
String ifRange = header.get("if-range");
String etag = Integer.toHexString((file.getAbsolutePath() + file.lastModified() + "" + file.length()).hashCode());
boolean headerIfRangeMissingOrMatching = (ifRange == null || etag.equals(ifRange));
String ifNoneMatch = header.get("if-none-match");
boolean headerIfNoneMatchPresentAndMatching = ifNoneMatch != null && ("*".equals(ifNoneMatch) || ifNoneMatch.equals(etag));
if (headerIfRangeMissingOrMatching && range != null && startFrom >= 0 && startFrom < fileLen) {
if (headerIfNoneMatchPresentAndMatching) {
if (ifRangeMatch && range != null && startFrom < fileLen) {
if (ifNoneMatchHit) {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_MODIFIED, mime, "");
res.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
res.addHeader(HttpHeaders.ETAG, etag);
contentLength = 0;
} else {
if (endAt < 0) endAt = fileLen - 1;
long newLen = endAt - startFrom + 1;
if (newLen < 0) newLen = 0;
FileInputStream fis = new FileInputStream(file);
fis.skip(startFrom);
long skipped = 0;
while (skipped < startFrom) {
long s = fis.skip(startFrom - skipped);
if (s <= 0) break;
skipped += s;
}
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.PARTIAL_CONTENT, mime, fis, newLen);
res.addHeader(HttpHeaders.CONTENT_LENGTH, newLen + "");
res.addHeader(HttpHeaders.CONTENT_RANGE, "bytes " + startFrom + "-" + endAt + "/" + fileLen);
res.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
res.addHeader(HttpHeaders.ETAG, etag);
res.addHeader("Content-Range", "bytes " + startFrom + "-" + endAt + "/" + fileLen);
contentLength = newLen;
}
} else if (range != null && startFrom >= fileLen) {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, "");
res.addHeader("Content-Range", "bytes */" + fileLen);
contentLength = 0;
} else if (ifNoneMatchHit) {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_MODIFIED, mime, "");
contentLength = 0;
} else {
if (headerIfRangeMissingOrMatching && range != null && startFrom >= fileLen) {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, "");
res.addHeader(HttpHeaders.CONTENT_RANGE, "bytes */" + fileLen);
res.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
res.addHeader(HttpHeaders.ETAG, etag);
} else if (headerIfNoneMatchPresentAndMatching && (!headerIfRangeMissingOrMatching || range == null)) {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_MODIFIED, mime, "");
res.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
res.addHeader(HttpHeaders.ETAG, etag);
} else {
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.OK, mime, new FileInputStream(file), (int) file.length());
res.addHeader(HttpHeaders.CONTENT_LENGTH, fileLen + "");
res.addHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
res.addHeader(HttpHeaders.ETAG, etag);
}
FileInputStream fis = new FileInputStream(file);
res = NanoHTTPD.newFixedLengthResponse(NanoHTTPD.Response.Status.OK, mime, fis, fileLen);
contentLength = fileLen;
}
res.addHeader("Content-Length", String.valueOf(contentLength));
res.addHeader("Accept-Ranges", "bytes");
res.addHeader("ETag", etag);
return res;
}
}

Loading…
Cancel
Save