From 27c7fb0c1281f72b814c0257bc70798cbbab1695 Mon Sep 17 00:00:00 2001 From: Koen Date: Wed, 15 Nov 2023 16:18:38 +0000 Subject: [PATCH] Content length is now set correctly for HttpConstantHandler. --- .../server/handlers/HttpConstantHandler.kt | 1 - .../http/server/handlers/HttpFileHandler.kt | 35 +++++++------------ .../http/server/handlers/HttpProxyHandler.kt | 11 ++++-- .../platformplayer/casting/StateCasting.kt | 2 +- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpConstantHandler.kt b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpConstantHandler.kt index c868b2b7..a58b163d 100644 --- a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpConstantHandler.kt +++ b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpConstantHandler.kt @@ -7,7 +7,6 @@ class HttpConstantHandler(method: String, path: String, val content: String, val val headers = this.headers.clone(); if(contentType != null) headers["Content-Type"] = contentType; - headers["Content-Length"] = content.length.toString(); httpContext.respondCode(200, headers, content); } diff --git a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpFileHandler.kt b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpFileHandler.kt index 89ad16c6..ac72f633 100644 --- a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpFileHandler.kt +++ b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpFileHandler.kt @@ -1,14 +1,16 @@ package com.futo.platformplayer.api.http.server.handlers import com.futo.platformplayer.api.http.server.HttpContext +import com.futo.platformplayer.api.http.server.HttpHeaders import com.futo.platformplayer.logging.Logger +import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Files import java.text.SimpleDateFormat import java.util.* import java.util.zip.GZIPOutputStream -class HttpFileHandler(method: String, path: String, private val contentType: String, private val filePath: String, private val closeAfterRequest: Boolean = false): HttpHandler(method, path) { +class HttpFileHandler(method: String, path: String, private val contentType: String, private val filePath: String): HttpHandler(method, path) { override fun handle(httpContext: HttpContext) { val requestHeaders = httpContext.headers; val responseHeaders = this.headers.clone(); @@ -30,19 +32,13 @@ class HttpFileHandler(method: String, path: String, private val contentType: Str responseHeaders["Content-Disposition"] = "attachment; filename=\"${file.name.replace("\"", "\\\"")}\"" - val acceptEncoding = requestHeaders["Accept-Encoding"] - val shouldGzip = acceptEncoding != null && acceptEncoding.split(',').any { it.trim().equals("gzip", ignoreCase = true) || it == "*" } - if (shouldGzip) { - responseHeaders["Content-Encoding"] = "gzip" - } - val range = requestHeaders["Range"] - var start: Long + val start: Long val end: Long if (range != null && range.startsWith("bytes=")) { val parts = range.substring(6).split("-") start = parts[0].toLong() - end = parts.getOrNull(1)?.toLong() ?: (file.length() - 1) + end = parts.getOrNull(1)?.toLongOrNull() ?: (file.length() - 1) responseHeaders["Content-Range"] = "bytes $start-$end/${file.length()}" } else { start = 0 @@ -51,18 +47,19 @@ class HttpFileHandler(method: String, path: String, private val contentType: Str var totalBytesSent = 0 val contentLength = end - start + 1 - Logger.i(TAG, "Sending $contentLength bytes (start: $start, end: $end, shouldGzip: $shouldGzip)") responseHeaders["Content-Length"] = contentLength.toString() + Logger.i(TAG, "Sending $contentLength bytes (start: $start, end: $end)") file.inputStream().use { inputStream -> - httpContext.respond(if (range == null) 200 else 206, responseHeaders) { responseStream -> + httpContext.respond(if (range != null) 206 else 200, responseHeaders) { responseStream -> try { val buffer = ByteArray(8192) inputStream.skip(start) + var current = start - val outputStream = if (shouldGzip) GZIPOutputStream(responseStream) else responseStream + val outputStream = responseStream while (true) { - val expectedBytesRead = (end - start + 1).coerceAtMost(buffer.size.toLong()); + val expectedBytesRead = (end - current + 1).coerceAtMost(buffer.size.toLong()); val bytesRead = inputStream.read(buffer); if (bytesRead < 0) { Logger.i(TAG, "End of file reached") @@ -73,27 +70,21 @@ class HttpFileHandler(method: String, path: String, private val contentType: Str outputStream.write(buffer, 0, bytesToSend) totalBytesSent += bytesToSend - Logger.v(TAG, "Sent bytes $start-${start + bytesToSend}, totalBytesSent=$totalBytesSent") + Logger.v(TAG, "Sent bytes $current-${current + bytesToSend}, totalBytesSent=$totalBytesSent") - start += bytesToSend.toLong() - if (start >= end) { + current += bytesToSend.toLong() + if (current >= end) { Logger.i(TAG, "Expected amount of bytes sent") break } } Logger.i(TAG, "Finished sending file (segment)") - - if (shouldGzip) (outputStream as GZIPOutputStream).finish() outputStream.flush() } catch (e: Exception) { httpContext.respondCode(500, headers) } } - - if (closeAfterRequest) { - httpContext.keepAlive = false; - } } } diff --git a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpProxyHandler.kt b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpProxyHandler.kt index 1756925c..f6774c1e 100644 --- a/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpProxyHandler.kt +++ b/app/src/main/java/com/futo/platformplayer/api/http/server/handlers/HttpProxyHandler.kt @@ -4,6 +4,7 @@ import android.net.Uri import com.futo.platformplayer.api.http.server.HttpContext import com.futo.platformplayer.api.http.server.HttpHeaders import com.futo.platformplayer.api.http.ManagedHttpClient +import com.futo.platformplayer.logging.Logger class HttpProxyHandler(method: String, path: String, val targetUrl: String): HttpHandler(method, path) { var content: String? = null; @@ -34,8 +35,8 @@ class HttpProxyHandler(method: String, path: String, val targetUrl: String): Htt proxyHeaders.put("Referer", targetUrl); val useMethod = if (method == "inherit") context.method else method; - //Logger.i(TAG, "Proxied Request ${useMethod}: ${targetUrl}"); - //Logger.i(TAG, "Headers:" + proxyHeaders.map { "${it.key}: ${it.value}" }.joinToString("\n")); + Logger.i(TAG, "Proxied Request ${useMethod}: ${targetUrl}"); + Logger.i(TAG, "Headers:" + proxyHeaders.map { "${it.key}: ${it.value}" }.joinToString("\n")); val resp = when (useMethod) { "GET" -> _client.get(targetUrl, proxyHeaders); @@ -44,7 +45,7 @@ class HttpProxyHandler(method: String, path: String, val targetUrl: String): Htt else -> _client.requestMethod(useMethod, targetUrl, proxyHeaders); }; - //Logger.i(TAG, "Proxied Response [${resp.code}]"); + Logger.i(TAG, "Proxied Response [${resp.code}]"); val headersFiltered = HttpHeaders(resp.getHeadersFlat().filter { !_ignoreRequestHeaders.contains(it.key.lowercase()) }); for(newHeader in headers) headersFiltered.put(newHeader.key, newHeader.value); @@ -92,4 +93,8 @@ class HttpProxyHandler(method: String, path: String, val targetUrl: String): Htt _ignoreRequestHeaders.add("referer"); return this; } + + companion object { + private const val TAG = "HttpProxyHandler" + } } \ No newline at end of file diff --git a/app/src/main/java/com/futo/platformplayer/casting/StateCasting.kt b/app/src/main/java/com/futo/platformplayer/casting/StateCasting.kt index 493218a2..6a3055e7 100644 --- a/app/src/main/java/com/futo/platformplayer/casting/StateCasting.kt +++ b/app/src/main/java/com/futo/platformplayer/casting/StateCasting.kt @@ -486,7 +486,7 @@ class StateCasting { } if (subtitleSource != null) { _castServer.addHandler( - HttpFileHandler("GET", subtitlePath, subtitleSource.format ?: "text/vtt", subtitleSource.filePath, true) + HttpFileHandler("GET", subtitlePath, subtitleSource.format ?: "text/vtt", subtitleSource.filePath) .withHeader("Access-Control-Allow-Origin", "*"), true ).withTag("cast"); _castServer.addHandler(