kotlin 修改

This commit is contained in:
“lushunming” 2025-07-20 17:45:31 +08:00
parent c523058923
commit a1f8601481
6 changed files with 54 additions and 92 deletions

View File

@ -47,32 +47,12 @@
# Please add these rules to your existing keep rules in order to suppress warnings. # Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin. # This is generated automatically by the Android Gradle plugin.
# Ignore warnings from Netty -dontwarn sun.misc.Service
-dontwarn io.netty.** -dontwarn sun.misc.ServiceConfigurationError
-dontwarn java.lang.management.ManagementFactory -dontwarn sun.security.action.GetBooleanAction
-dontwarn java.lang.management.RuntimeMXBean -dontwarn sun.security.action.GetIntegerAction
-dontwarn org.apache.log4j.Level -dontwarn sun.security.action.GetLongAction
-dontwarn org.apache.log4j.Logger
-dontwarn org.apache.log4j.Priority
-dontwarn org.apache.logging.log4j.Level
-dontwarn org.apache.logging.log4j.LogManager
-dontwarn org.apache.logging.log4j.Logger
-dontwarn org.apache.logging.log4j.message.MessageFactory
-dontwarn org.apache.logging.log4j.spi.ExtendedLogger
-dontwarn org.apache.logging.log4j.spi.ExtendedLoggerWrapper
-dontwarn org.conscrypt.BufferAllocator
-dontwarn org.conscrypt.Conscrypt
-dontwarn org.conscrypt.HandshakeListener
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ClientProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$Provider
-dontwarn org.eclipse.jetty.npn.NextProtoNego$ServerProvider
-dontwarn org.eclipse.jetty.npn.NextProtoNego
-dontwarn reactor.blockhound.integration.BlockHoundIntegration
# Ktor Server
-keep class io.ktor.server.config.HoconConfigLoader { *; }
# Logback (Custom rules, see https://github.com/krschultz/android-proguard-snippets/blob/master/libraries/proguard-logback-android.pro) # Logback (Custom rules, see https://github.com/krschultz/android-proguard-snippets/blob/master/libraries/proguard-logback-android.pro)
@ -94,52 +74,7 @@
-keepattributes SourceFile,LineNumberTable -keepattributes SourceFile,LineNumberTable
-keepattributes Signature,InnerClasses
# 保留所有 Netty
-keep class io.netty.** { *; }
# 保留 Netty 的内部类
-keep class io.netty.**$* { *; }
# 保留 Netty 的注解
-keep @interface io.netty.**
# 保留 Netty native 方法
-keepclasseswithmembernames,includedescriptorclasses class io.netty.** {
native <methods>;
}
# 保留 Netty 的序列化相关类
-keepclassmembers class io.netty.** implements java.io.Serializable {
static final long serialVersionUID;
private static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# 保留 Netty ChannelFuture 相关类
-keep class io.netty.channel.ChannelFuture { *; }
-keep class io.netty.util.concurrent.Future { *; }
# 保留 Netty 的异常类
-keep class io.netty.** extends java.lang.Exception { *; }
# 保留 Netty 的注解处理器
-keepclassmembers class * extends io.netty.** {
@io.netty.** *;
}
# 不警告 Netty 相关的类
-dontwarn io.netty.**
# Please add these rules to your existing keep rules in order to suppress warnings.
# This is generated automatically by the Android Gradle plugin.
-dontwarn java.beans.BeanInfo
-dontwarn java.beans.IntrospectionException
-dontwarn java.beans.Introspector
-dontwarn java.beans.PropertyDescriptor
-dontwarn javax.lang.model.element.Modifier

View File

@ -11,6 +11,9 @@ import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import okhttp3.Headers
import java.io.BufferedOutputStream
import java.io.ByteArrayOutputStream
import java.io.OutputStreamWriter import java.io.OutputStreamWriter
import java.net.InetSocketAddress import java.net.InetSocketAddress
import java.nio.charset.Charset import java.nio.charset.Charset
@ -21,6 +24,7 @@ object ProxyServer {
private const val partSize = 1024 * 1024 * 1 private const val partSize = 1024 * 1024 * 1
private var port = 0 private var port = 0
private var httpServer: HttpServer? = null private var httpServer: HttpServer? = null
private val infos = mutableMapOf<String, MutableMap<String, MutableList<String>>>();
fun stop() { fun stop() {
httpServer?.stop(1_000) httpServer?.stop(1_000)
@ -33,6 +37,8 @@ object ProxyServer {
httpServer = HttpServer.create(InetSocketAddress(port), 100); httpServer = HttpServer.create(InetSocketAddress(port), 100);
httpServer?.createContext("/") { httpExchange -> httpServer?.createContext("/") { httpExchange ->
run { run {
httpExchange.sendResponseHeaders(200, "server running ".length.toLong());
val os = httpExchange.responseBody val os = httpExchange.responseBody
val writer = OutputStreamWriter(os, Charset.defaultCharset()) val writer = OutputStreamWriter(os, Charset.defaultCharset())
writer.write("server running ") writer.write("server running ")
@ -68,8 +74,8 @@ object ProxyServer {
httpServer?.stop(1000) httpServer?.stop(1000)
} }
port = httpServer?.address?.port!!
SpiderDebug.log("ktorServer start on " + httpServer?.address?.port) SpiderDebug.log("ktorServer start on " + port)
} }
@ -78,6 +84,9 @@ object ProxyServer {
) { ) {
val channels = List(THREAD_NUM) { Channel<ByteArray>() } val channels = List(THREAD_NUM) { Channel<ByteArray>() }
val outputStream = httpExchange.responseBody val outputStream = httpExchange.responseBody
val bufferedOutputStream = BufferedOutputStream(outputStream)
try { try {
SpiderDebug.log("--proxyMultiThread: THREAD_NUM: $THREAD_NUM") SpiderDebug.log("--proxyMultiThread: THREAD_NUM: $THREAD_NUM")
@ -96,15 +105,24 @@ object ProxyServer {
val (startPoint, endPoint) = parseRangePoint( val (startPoint, endPoint) = parseRangePoint(
rangeHeader rangeHeader
) )
//缓存response header
var info = infos[url]
if (info == null) {
info = getInfo(url, headers)
infos[url] = info
}
SpiderDebug.log("startPoint: $startPoint; endPoint: $endPoint") SpiderDebug.log("startPoint: $startPoint; endPoint: $endPoint")
val contentLength = getContentLength(url, headers) val contentLength = getContentLength(info)
SpiderDebug.log("contentLength: $contentLength") SpiderDebug.log("contentLength: $contentLength")
val finalEndPoint = if (endPoint == -1L) contentLength - 1 else endPoint val finalEndPoint = if (endPoint == -1L) contentLength - 1 else endPoint
httpExchange.responseHeaders.apply { httpExchange.responseHeaders.apply {
set("Connection", "keep-alive") set("Connection", "keep-alive")
set("ContentLength", (finalEndPoint - startPoint + 1).toString()) set("Content-Length", (finalEndPoint - startPoint + 1).toString())
set("ContentRange", "bytes $startPoint-$finalEndPoint/$contentLength") set("Content-Range", "bytes $startPoint-$finalEndPoint/$contentLength")
set("Content-Type", info["Content-Type"]?.get(0))
} }
httpExchange.sendResponseHeaders(206, 0) httpExchange.sendResponseHeaders(206, 0)
@ -138,23 +156,23 @@ object ProxyServer {
val data = channels[index].receive() val data = channels[index].receive()
SpiderDebug.log("Received chunk: ${data.size} bytes") SpiderDebug.log("Received chunk: ${data.size} bytes")
CoroutineScope(Dispatchers.IO).launch {
outputStream.write(data)
}
}
bufferedOutputStream.write(data)
bufferedOutputStream.flush()
}
} }
} catch (e: Exception) { } catch (e: Exception) {
SpiderDebug.log("error: ${e.message}") SpiderDebug.log("error: ${e.message}")
withContext(Dispatchers.IO) {
outputStream.write("error: ${e.message}".toByteArray()) outputStream.write("error: ${e.message}".toByteArray())
}
} finally { } finally {
channels.forEach { it.close() } channels.forEach { it.close() }
withContext(Dispatchers.IO) { bufferedOutputStream.close()
outputStream.close() outputStream.close()
}
httpExchange.close() httpExchange.close()
} }
} }
@ -185,11 +203,20 @@ object ProxyServer {
return start to end return start to end
} }
private fun getContentLength(url: String, headers: Map<String, String>): Long { fun getInfo(
// 实现获取内容长度逻辑 url: String?, headers: Map<String, String>
): MutableMap<String, MutableList<String>> {
val newHeaders: MutableMap<String, String> = java.util.HashMap(headers)
newHeaders["Range"] = "bytes=0-" + (1024 * 1024 - 1)
newHeaders["range"] = "bytes=0-" + (1024 * 1024 - 1)
val res = OkHttp.newCall(url, headers) val res = OkHttp.newCall(url, headers)
res.body()?.close() res.body()?.close()
return res.headers("Content-Length")[0]?.toLong() ?: 0L return res.headers().toMultimap()
}
private fun getContentLength(info: MutableMap<String, MutableList<String>>): Long {
// 实现获取内容长度逻辑
return info["Content-Length"]?.get(0)?.toLong() ?: 0L
} }
private fun getVideoStream( private fun getVideoStream(

View File

@ -6,7 +6,7 @@ import org.robolectric.RobolectricTestRunner;
import java.util.HashMap; import java.util.HashMap;
//@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class ProxyVideoTest { public class ProxyVideoTest {
@Test @Test
@ -18,7 +18,7 @@ public class ProxyVideoTest {
"http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>()); "http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>());
System.out.println(url);*/ System.out.println(url);*/
ProxyServer.INSTANCE.start(); ProxyServer.INSTANCE.start();
System.out.println(ProxyServer.INSTANCE.buildProxyUrl("http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>())); System.out.println(ProxyServer.INSTANCE.buildProxyUrl("https://media.w3.org/2010/05/sintel/trailer.mp4", new HashMap<>()));
while (true) { while (true) {
} }

Binary file not shown.

View File

@ -1 +1 @@
9013187cddf48a5b4bf4604b07dd534b 2b55efe5a17ba216363ab2bef3b69d05

View File

@ -1,5 +1,5 @@
{ {
"spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;8a9fee904fd090f7eb5ec9eb73fc257a", "spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;2b55efe5a17ba216363ab2bef3b69d05",
"lives": [ "lives": [
{ {
"name": "电视直播", "name": "电视直播",