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.
|
# 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -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.
|
|
@ -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": [
|
"lives": [
|
||||||
{
|
{
|
||||||
"name": "电视直播",
|
"name": "电视直播",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue