kotlin 修改
This commit is contained in:
parent
c523058923
commit
a1f8601481
|
|
@ -47,32 +47,12 @@
|
|||
|
||||
# Please add these rules to your existing keep rules in order to suppress warnings.
|
||||
# This is generated automatically by the Android Gradle plugin.
|
||||
# Ignore warnings from Netty
|
||||
-dontwarn io.netty.**
|
||||
-dontwarn java.lang.management.ManagementFactory
|
||||
-dontwarn java.lang.management.RuntimeMXBean
|
||||
-dontwarn org.apache.log4j.Level
|
||||
-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
|
||||
-dontwarn sun.misc.Service
|
||||
-dontwarn sun.misc.ServiceConfigurationError
|
||||
-dontwarn sun.security.action.GetBooleanAction
|
||||
-dontwarn sun.security.action.GetIntegerAction
|
||||
-dontwarn sun.security.action.GetLongAction
|
||||
|
||||
# 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)
|
||||
|
|
@ -94,52 +74,7 @@
|
|||
|
||||
-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
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ import kotlinx.coroutines.Job
|
|||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import okhttp3.Headers
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.charset.Charset
|
||||
|
|
@ -21,6 +24,7 @@ object ProxyServer {
|
|||
private const val partSize = 1024 * 1024 * 1
|
||||
private var port = 0
|
||||
private var httpServer: HttpServer? = null
|
||||
private val infos = mutableMapOf<String, MutableMap<String, MutableList<String>>>();
|
||||
|
||||
fun stop() {
|
||||
httpServer?.stop(1_000)
|
||||
|
|
@ -33,6 +37,8 @@ object ProxyServer {
|
|||
httpServer = HttpServer.create(InetSocketAddress(port), 100);
|
||||
httpServer?.createContext("/") { httpExchange ->
|
||||
run {
|
||||
httpExchange.sendResponseHeaders(200, "server running ".length.toLong());
|
||||
|
||||
val os = httpExchange.responseBody
|
||||
val writer = OutputStreamWriter(os, Charset.defaultCharset())
|
||||
writer.write("server running ")
|
||||
|
|
@ -68,8 +74,8 @@ object ProxyServer {
|
|||
|
||||
httpServer?.stop(1000)
|
||||
}
|
||||
|
||||
SpiderDebug.log("ktorServer start on " + httpServer?.address?.port)
|
||||
port = httpServer?.address?.port!!
|
||||
SpiderDebug.log("ktorServer start on " + port)
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -78,6 +84,9 @@ object ProxyServer {
|
|||
) {
|
||||
val channels = List(THREAD_NUM) { Channel<ByteArray>() }
|
||||
val outputStream = httpExchange.responseBody
|
||||
|
||||
val bufferedOutputStream = BufferedOutputStream(outputStream)
|
||||
|
||||
try {
|
||||
SpiderDebug.log("--proxyMultiThread: THREAD_NUM: $THREAD_NUM")
|
||||
|
||||
|
|
@ -96,15 +105,24 @@ object ProxyServer {
|
|||
val (startPoint, endPoint) = parseRangePoint(
|
||||
rangeHeader
|
||||
)
|
||||
|
||||
//缓存response header
|
||||
var info = infos[url]
|
||||
if (info == null) {
|
||||
info = getInfo(url, headers)
|
||||
infos[url] = info
|
||||
}
|
||||
|
||||
SpiderDebug.log("startPoint: $startPoint; endPoint: $endPoint")
|
||||
val contentLength = getContentLength(url, headers)
|
||||
val contentLength = getContentLength(info)
|
||||
SpiderDebug.log("contentLength: $contentLength")
|
||||
val finalEndPoint = if (endPoint == -1L) contentLength - 1 else endPoint
|
||||
|
||||
httpExchange.responseHeaders.apply {
|
||||
set("Connection", "keep-alive")
|
||||
set("ContentLength", (finalEndPoint - startPoint + 1).toString())
|
||||
set("ContentRange", "bytes $startPoint-$finalEndPoint/$contentLength")
|
||||
set("Content-Length", (finalEndPoint - startPoint + 1).toString())
|
||||
set("Content-Range", "bytes $startPoint-$finalEndPoint/$contentLength")
|
||||
set("Content-Type", info["Content-Type"]?.get(0))
|
||||
}
|
||||
httpExchange.sendResponseHeaders(206, 0)
|
||||
|
||||
|
|
@ -138,23 +156,23 @@ object ProxyServer {
|
|||
|
||||
val data = channels[index].receive()
|
||||
SpiderDebug.log("Received chunk: ${data.size} bytes")
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
outputStream.write(data)
|
||||
}
|
||||
}
|
||||
|
||||
bufferedOutputStream.write(data)
|
||||
bufferedOutputStream.flush()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("error: ${e.message}")
|
||||
withContext(Dispatchers.IO) {
|
||||
|
||||
outputStream.write("error: ${e.message}".toByteArray())
|
||||
}
|
||||
|
||||
} finally {
|
||||
channels.forEach { it.close() }
|
||||
withContext(Dispatchers.IO) {
|
||||
bufferedOutputStream.close()
|
||||
outputStream.close()
|
||||
}
|
||||
|
||||
httpExchange.close()
|
||||
}
|
||||
}
|
||||
|
|
@ -185,11 +203,20 @@ object ProxyServer {
|
|||
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)
|
||||
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(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import org.robolectric.RobolectricTestRunner;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
//@RunWith(RobolectricTestRunner.class)
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ProxyVideoTest {
|
||||
|
||||
@Test
|
||||
|
|
@ -18,7 +18,7 @@ public class ProxyVideoTest {
|
|||
"http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>());
|
||||
System.out.println(url);*/
|
||||
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) {
|
||||
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
9013187cddf48a5b4bf4604b07dd534b
|
||||
2b55efe5a17ba216363ab2bef3b69d05
|
||||
|
|
|
|||
|
|
@ -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": [
|
||||
{
|
||||
"name": "电视直播",
|
||||
|
|
|
|||
Loading…
Reference in New Issue