licuri-server/src/main/java/com/dlnapps/controller/DlnaAction.java
private Response serveFile(String uri, Map<String, String> header, File file, String mime, String fileName) {
	Response res;
	try {
	    // Calculate etag
	    String etag = Integer.toHexString((file.getAbsolutePath() + file.lastModified() + "" + file.length()).hashCode());

	    // Support (simple) skipping:
	    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) {
		    }
		}
	    }

	    // Change return code and add Content-Range header when skipping is
	    // requested
	    long fileLen = file.length();
	    if (range != null && startFrom >= 0) {
		if (startFrom >= fileLen) {
		    res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, "");
		    res.addHeader("Content-Range", "bytes 0-0/" + fileLen);
		    res.addHeader("ETag", etag);
		} else {
		    if (endAt < 0) {
			endAt = fileLen - 1;
		    }
		    long newLen = endAt - startFrom + 1;
		    if (newLen < 0) {
			newLen = 0;
		    }

		    final long dataLen = newLen;
		    FileInputStream fis = new FileInputStream(file) {
			@Override
			public int available() throws IOException {
			    return (int) dataLen;
			}
		    };
		    fis.skip(startFrom);

		    res = createResponse(Response.Status.PARTIAL_CONTENT, mime, fis);
		    res.addHeader("Content-Length", "" + dataLen);
		    res.addHeader("Content-Range", "bytes " + startFrom + "-" + endAt + "/" + fileLen);
		    res.addHeader("ETag", etag);
		}

	    } else {
		if (etag.equals(header.get("if-none-match")))
		    res = createResponse(Response.Status.NOT_MODIFIED, mime, "");
		else {
		    res = createResponse(Response.Status.OK, mime, new FileInputStream(file));
		    res.addHeader("Content-Length", "" + fileLen);
		    res.addHeader("ETag", etag);

		}
	    }
	    res.addHeader("CaptionInfo.sec", createCaptionInfoHeader(fileName));
	} catch (IOException ioe) {
	    res = createResponse(Response.Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: Reading file failed.");
	}

	return res;
    }
/**
     * Serves file from homeDir and its' subdirectories (only). Uses only URI,
     * ignores all headers and HTTP parameters.
     * 
     * @param fileName
     */
Serves file from homeDir and its' subdirectories (only). Uses only URI,
ignores all headers and HTTP parameters.

@param fileName
Serves file from homeDir and its ' subdirectories ( only ) . Uses only URI ignores all headers and HTTP parameters . @param fileName
private Response serveFile(String uri, Map<String, String> header, File file, String mime, String fileName) {
	Response res;
	try {
	    String etag = Integer.toHexString((file.getAbsolutePath() + file.lastModified() + "" + file.length()).hashCode());
	    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) {
		    }
		}
	    }
	    long fileLen = file.length();
	    if (range != null && startFrom >= 0) {
		if (startFrom >= fileLen) {
		    res = createResponse(Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, "");
		    res.addHeader("Content-Range", "bytes 0-0/" + fileLen);
		    res.addHeader("ETag", etag);
		} else {
		    if (endAt < 0) {
			endAt = fileLen - 1;
		    }
		    long newLen = endAt - startFrom + 1;
		    if (newLen < 0) {
			newLen = 0;
		    }
		    final long dataLen = newLen;
		    FileInputStream fis = new FileInputStream(file) {
			@Override
			public int available() throws IOException {
			    return (int) dataLen;
			}
		    };
		    fis.skip(startFrom);
		    res = createResponse(Response.Status.PARTIAL_CONTENT, mime, fis);
		    res.addHeader("Content-Length", "" + dataLen);
		    res.addHeader("Content-Range", "bytes " + startFrom + "-" + endAt + "/" + fileLen);
		    res.addHeader("ETag", etag);
		}
	    } else {
		if (etag.equals(header.get("if-none-match")))
		    res = createResponse(Response.Status.NOT_MODIFIED, mime, "");
		else {
		    res = createResponse(Response.Status.OK, mime, new FileInputStream(file));
		    res.addHeader("Content-Length", "" + fileLen);
		    res.addHeader("ETag", etag);
		}
	    }
	    res.addHeader("CaptionInfo.sec", createCaptionInfoHeader(fileName));
	} catch (IOException ioe) {
	    res = createResponse(Response.Status.FORBIDDEN, NanoHTTPD.MIME_PLAINTEXT, "FORBIDDEN: Reading file failed.");
	}
	return res;
    }
private Response serveFile ( String uri , Map < String , String > header , File file , String mime , String fileName ) { Response res ; try { String etag = Integer . toHexString ( ( file . getAbsolutePath ( ) + file . lastModified ( ) + "" + file . length ( ) ) . hashCode ( ) ) ; 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 ) { } } } long fileLen = file . length ( ) ; if ( range != null && startFrom >= 0 ) { if ( startFrom >= fileLen ) { res = createResponse ( Response . Status . RANGE_NOT_SATISFIABLE , NanoHTTPD . MIME_PLAINTEXT , "" ) ; res . addHeader ( "Content-Range" , "bytes 0-0/" + fileLen ) ; res . addHeader ( "ETag" , etag ) ; } else { if ( endAt < 0 ) { endAt = fileLen - 1 ; } long newLen = endAt - startFrom + 1 ; if ( newLen < 0 ) { newLen = 0 ; } final long dataLen = newLen ; FileInputStream fis = new FileInputStream ( file ) { @ Override public int available ( ) throws IOException { return ( int ) dataLen ; } } ; fis . skip ( startFrom ) ; res = createResponse ( Response . Status . PARTIAL_CONTENT , mime , fis ) ; res . addHeader ( "Content-Length" , "" + dataLen ) ; res . addHeader ( "Content-Range" , "bytes " + startFrom + "-" + endAt + "/" + fileLen ) ; res . addHeader ( "ETag" , etag ) ; } } else { if ( etag . equals ( header . get ( "if-none-match" ) ) ) res = createResponse ( Response . Status . NOT_MODIFIED , mime , "" ) ; else { res = createResponse ( Response . Status . OK , mime , new FileInputStream ( file ) ) ; res . addHeader ( "Content-Length" , "" + fileLen ) ; res . addHeader ( "ETag" , etag ) ; } } res . addHeader ( "CaptionInfo.sec" , createCaptionInfoHeader ( fileName ) ) ; } catch ( IOException ioe ) { res = createResponse ( Response . Status . FORBIDDEN , NanoHTTPD . MIME_PLAINTEXT , "FORBIDDEN: Reading file failed." ) ; } return res ; }
Serves file from homeDir and its' subdirectories (only).
Serves file from homeDir and its ' subdirectories ( only ) .
// Calculate etag
 // Support (simple) skipping:
 // Change return code and add Content-Range header when skipping is
 // requested
