httpserver
This commit is contained in:
parent
7e65d5eae0
commit
b5a1f6ef04
|
|
@ -86,10 +86,10 @@ dependencies {
|
|||
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1"
|
||||
// https://mvnrepository.com/artifact/com.sun.net.httpserver/http
|
||||
|
||||
// implementation("com.sun.net.httpserver:http:20070405")
|
||||
implementation(files("libs/sun-common-server.jar"))
|
||||
implementation("com.sun.net.httpserver:http:20070405")
|
||||
// implementation("com.hibegin:simplewebserver:0.1.15")
|
||||
implementation("com.github.codeborne.klite:klite-server:1.7.0")
|
||||
//implementation("com.github.codeborne.klite:klite-server:1.7.0")
|
||||
|
||||
|
||||
//implementation 'wang.harlon.quickjs:wrapper-java:1.0.0'
|
||||
|
|
|
|||
|
|
@ -1,10 +1,17 @@
|
|||
package com.github.catvod.utils
|
||||
|
||||
|
||||
import com.github.catvod.crawler.SpiderDebug
|
||||
import com.github.catvod.net.OkHttp
|
||||
import com.google.gson.Gson
|
||||
import klite.Server
|
||||
import com.sun.net.httpserver.HttpExchange
|
||||
import com.sun.net.httpserver.HttpServer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.InetSocketAddress
|
||||
import java.nio.charset.Charset
|
||||
|
||||
|
|
@ -13,59 +20,75 @@ object ProxyServer {
|
|||
private val THREAD_NUM = Runtime.getRuntime().availableProcessors() * 2
|
||||
private const val partSize = 1024 * 1024 * 1
|
||||
private var port = 12345
|
||||
private var server: Server? = null
|
||||
private var httpServer: HttpServer? = null
|
||||
private val infos = mutableMapOf<String, MutableMap<String, MutableList<String>>>();
|
||||
|
||||
fun stop() {
|
||||
server?.stop(1000)
|
||||
httpServer?.stop(1_000)
|
||||
}
|
||||
|
||||
fun start() {
|
||||
|
||||
|
||||
try {
|
||||
server = Server(InetSocketAddress(port)).apply {
|
||||
context("/api") {
|
||||
get("/hello") { "Hello, world!" }
|
||||
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 ")
|
||||
writer.close()
|
||||
os.close()
|
||||
httpExchange.close()
|
||||
}
|
||||
start()
|
||||
}
|
||||
httpServer?.createContext("/proxy") { httpExchange ->
|
||||
run {
|
||||
val params = queryToMap(httpExchange.requestURI.query)
|
||||
|
||||
val url = Util.base64Decode(params?.get("url"))
|
||||
val header: Map<String, String> = Gson().fromJson<Map<String, String>>(
|
||||
Util.base64Decode(params?.get("headers")), MutableMap::class.java
|
||||
)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
proxyAsync(
|
||||
url, header, httpExchange
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
httpServer?.executor = null;
|
||||
|
||||
httpServer?.start();
|
||||
|
||||
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("start server e:" + e.message)
|
||||
e.printStackTrace()
|
||||
|
||||
stop()
|
||||
httpServer?.stop(1000)
|
||||
}
|
||||
SpiderDebug.log("Server start on " + port)
|
||||
port = httpServer?.address?.port!!
|
||||
SpiderDebug.log("ktorServer start on " + port)
|
||||
|
||||
}
|
||||
|
||||
/*class ProxyController : Controller() {
|
||||
fun index() {
|
||||
|
||||
val url = Util.base64Decode(getRequest().getParaToStr("url"))
|
||||
val header: Map<String, String> = Gson().fromJson<Map<String, String>>(
|
||||
Util.base64Decode(getRequest().getParaToStr("headers")), MutableMap::class.java
|
||||
)
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
proxyAsync(
|
||||
url, header, getRequest(), getResponse()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun proxyAsync(
|
||||
url: String, headers: Map<String, String>, request: HttpRequest, response: HttpResponse
|
||||
url: String, headers: Map<String, String>, httpExchange: HttpExchange
|
||||
) {
|
||||
val channels = List(THREAD_NUM) { Channel<ByteArray>() }
|
||||
var outputStream = ByteArrayOutputStream()
|
||||
val outputStream = httpExchange.responseBody
|
||||
|
||||
val bufferedOutputStream = BufferedOutputStream(outputStream)
|
||||
|
||||
try {
|
||||
SpiderDebug.log("--proxyMultiThread: THREAD_NUM: $THREAD_NUM")
|
||||
|
||||
|
||||
var rangeHeader = request.getHeader("Range")
|
||||
var rangeHeader = httpExchange.requestHeaders.getFirst("Range")
|
||||
//没有range头
|
||||
if (rangeHeader.isNullOrEmpty()) {
|
||||
// 处理初始请求
|
||||
|
|
@ -92,22 +115,15 @@ object ProxyServer {
|
|||
SpiderDebug.log("contentLength: $contentLength")
|
||||
val finalEndPoint = if (endPoint == -1L) contentLength - 1 else endPoint
|
||||
|
||||
|
||||
response.addHeader("Connection", "keep-alive")
|
||||
response.addHeader("Content-Length", (finalEndPoint - startPoint + 1).toString())
|
||||
response.addHeader("Content-Range", "bytes $startPoint-$finalEndPoint/$contentLength")
|
||||
response.addHeader("Content-Type", info["Content-Type"]?.get(0))
|
||||
val statusCode = 206
|
||||
val sb = StringBuilder();
|
||||
sb.append("HTTP/1.1 ").append(" ").append(statusCode).append(" ")
|
||||
.append(StatusCodeUtil.getStatusCode(statusCode)).append("\r\n")
|
||||
for ((key, value) in response.header) {
|
||||
sb.append(key).append(": ").append(value).append("\r\n")
|
||||
httpExchange.responseHeaders.apply {
|
||||
set("Connection", "keep-alive")
|
||||
set("Content-Length", (finalEndPoint - startPoint + 1).toString())
|
||||
set("Content-Range", "bytes $startPoint-$finalEndPoint/$contentLength")
|
||||
set("Content-Type", info["Content-Type"]?.get(0))
|
||||
}
|
||||
sb.append("\r\n")
|
||||
outputStream.write(sb.toString().toByteArray(Charset.defaultCharset()))
|
||||
outputStream.flush()
|
||||
response.send(outputStream, false)
|
||||
httpExchange.sendResponseHeaders(206, 0)
|
||||
|
||||
// 使用流式响应
|
||||
|
||||
var currentStart = startPoint
|
||||
|
||||
|
|
@ -122,9 +138,7 @@ object ProxyServer {
|
|||
|
||||
for (i in 0 until THREAD_NUM) {
|
||||
|
||||
if (currentStart > finalEndPoint) {
|
||||
break
|
||||
}
|
||||
if (currentStart > finalEndPoint) break
|
||||
val chunkStart = currentStart
|
||||
val chunkEnd = minOf(currentStart + partSize - 1, finalEndPoint)
|
||||
producerJob += CoroutineScope(Dispatchers.IO).launch {
|
||||
|
|
@ -139,30 +153,27 @@ object ProxyServer {
|
|||
|
||||
val data = channels[index].receive()
|
||||
SpiderDebug.log("Received chunk: ${data.size} bytes")
|
||||
outputStream = ByteArrayOutputStream();
|
||||
outputStream.write(data);
|
||||
outputStream.flush()
|
||||
|
||||
response.send(outputStream, false)
|
||||
// bufferedOutputStream.close()
|
||||
|
||||
bufferedOutputStream.write(data)
|
||||
bufferedOutputStream.flush()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
response.send(ByteArrayOutputStream(), true)
|
||||
} catch (e: Exception) {
|
||||
SpiderDebug.log("error: ${e.message}")
|
||||
|
||||
e.printStackTrace()
|
||||
outputStream.write("error: ${e.message}".toByteArray())
|
||||
|
||||
} finally {
|
||||
channels.forEach { it.close() }
|
||||
bufferedOutputStream.close()
|
||||
outputStream.close()
|
||||
|
||||
httpExchange.close()
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private fun queryToMap(query: String?): Map<String, String>? {
|
||||
if (query == null) {
|
||||
return null
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1 +1 @@
|
|||
46a0bc151a572484c98dc163e9b944dd
|
||||
822127bc7ad6da1d93a4ef9f8b9f15a1
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;46a0bc151a572484c98dc163e9b944dd",
|
||||
"spider": "https://gh.llkk.cc/https://raw.githubusercontent.com/lushunming/AndroidCatVodSpider/multiThreadNew/jar/custom_spider.jar;md5;822127bc7ad6da1d93a4ef9f8b9f15a1",
|
||||
"lives": [
|
||||
{
|
||||
"name": "电视直播",
|
||||
|
|
|
|||
Loading…
Reference in New Issue