mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-08-03 14:50:49 +00:00
Fix communication issues devportal
This commit is contained in:
parent
1393c489c1
commit
7fa80ec048
5 changed files with 75 additions and 24 deletions
|
@ -7,13 +7,15 @@ import com.futo.platformplayer.api.media.Serializer
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.io.BufferedInputStream
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedReader
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import java.net.SocketTimeoutException
|
import java.net.SocketTimeoutException
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
class HttpContext : AutoCloseable {
|
class HttpContext : AutoCloseable {
|
||||||
private val _stream: BufferedReader;
|
private val _stream: BufferedInputStream;
|
||||||
private var _responseStream: OutputStream? = null;
|
private var _responseStream: OutputStream? = null;
|
||||||
|
|
||||||
var id: String? = null;
|
var id: String? = null;
|
||||||
|
@ -38,14 +40,40 @@ class HttpContext : AutoCloseable {
|
||||||
|
|
||||||
private val _responseHeaders: HttpHeaders = HttpHeaders();
|
private val _responseHeaders: HttpHeaders = HttpHeaders();
|
||||||
|
|
||||||
|
private val newLineByte = "\n"[0];
|
||||||
|
private fun readStreamLine(): String {
|
||||||
|
//TODO: This is not ideal..
|
||||||
|
var twoByteArray = ByteBuffer.allocate(2);
|
||||||
|
var lastChar: Char = Char.MIN_VALUE;
|
||||||
|
val builder = StringBuilder();
|
||||||
|
do {
|
||||||
|
val firstByte = _stream.read();
|
||||||
|
if(firstByte == -1)
|
||||||
|
break;
|
||||||
|
if(isCharacter2Bytes(firstByte)) {
|
||||||
|
twoByteArray.put(0, firstByte.toByte());
|
||||||
|
val secondByte = _stream.read();
|
||||||
|
if(secondByte == -1)
|
||||||
|
break;
|
||||||
|
twoByteArray.put(1, secondByte.toByte());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lastChar = firstByte.toChar();
|
||||||
|
builder.append(lastChar);
|
||||||
|
if(lastChar == newLineByte)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while(lastChar != Char.MIN_VALUE);
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
constructor(stream: BufferedReader, responseStream: OutputStream? = null, requestId: String? = null, timeout: Int? = null) {
|
constructor(stream: BufferedInputStream, responseStream: OutputStream? = null, requestId: String? = null, timeout: Int? = null) {
|
||||||
_stream = stream;
|
_stream = stream;
|
||||||
_responseStream = responseStream;
|
_responseStream = responseStream;
|
||||||
this.id = requestId;
|
this.id = requestId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
head = stream.readLine() ?: throw EmptyRequestException("No head found");
|
head = readStreamLine() ?: throw EmptyRequestException("No head found");
|
||||||
}
|
}
|
||||||
catch(ex: SocketTimeoutException) {
|
catch(ex: SocketTimeoutException) {
|
||||||
if((timeout ?: 0) > 0)
|
if((timeout ?: 0) > 0)
|
||||||
|
@ -78,7 +106,7 @@ class HttpContext : AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
val line = stream.readLine();
|
val line = readStreamLine();
|
||||||
val headerEndIndex = line.indexOf(":");
|
val headerEndIndex = line.indexOf(":");
|
||||||
if (headerEndIndex == -1)
|
if (headerEndIndex == -1)
|
||||||
break;
|
break;
|
||||||
|
@ -172,27 +200,37 @@ class HttpContext : AutoCloseable {
|
||||||
statusCode = status;
|
statusCode = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readContentBytes(buffer: CharArray, length: Int) : Int {
|
fun readContentBytes(buffer: ByteArray, length: Int) : Int {
|
||||||
val reading = Math.min(length, (contentLength - _totalRead).toInt());
|
val reading = if(contentLength - _totalRead < length)
|
||||||
|
(contentLength - _totalRead).toInt();
|
||||||
|
else
|
||||||
|
length;
|
||||||
val read = _stream.read(buffer, 0, reading);
|
val read = _stream.read(buffer, 0, reading);
|
||||||
_totalRead += read;
|
_totalRead += read;
|
||||||
|
|
||||||
//TODO: Fix this properly
|
|
||||||
if(contentLength - _totalRead < 400 && read < length) {
|
|
||||||
_totalRead = contentLength;
|
|
||||||
}
|
|
||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
fun readContentString() : String{
|
fun readContentString() : String{
|
||||||
val writer = StringWriter();
|
val writer = StringWriter();
|
||||||
var read = 0;
|
var read = 0;
|
||||||
val buffer = CharArray(4096);
|
val buffer = ByteArray(8192);
|
||||||
|
val twoByteArray = ByteArray(2);
|
||||||
do {
|
do {
|
||||||
read = readContentBytes(buffer, buffer.size);
|
read = readContentBytes(buffer, buffer.size);
|
||||||
writer.write(buffer, 0, read);
|
|
||||||
} while(read > 0);// && _stream.ready());
|
if(read > 0) {
|
||||||
//if(!_stream.ready())
|
if (isCharacter2Bytes(buffer[read - 1].toInt())) {
|
||||||
// _totalRead = contentLength;
|
//Fixes overlapping buffers
|
||||||
|
writer.write(String(buffer, 0, read - 1));
|
||||||
|
twoByteArray[0] = buffer[read - 1];
|
||||||
|
val secondByte = _stream.read();
|
||||||
|
if (secondByte < 0)
|
||||||
|
break;
|
||||||
|
twoByteArray[1] = secondByte.toByte();
|
||||||
|
writer.write(String(twoByteArray));
|
||||||
|
} else
|
||||||
|
writer.write(String(buffer, 0, read));
|
||||||
|
}
|
||||||
|
} while(read > 0);
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
inline fun <reified T> readContentJson() : T {
|
inline fun <reified T> readContentJson() : T {
|
||||||
|
@ -210,6 +248,10 @@ class HttpContext : AutoCloseable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isCharacter2Bytes(firstByte: Int): Boolean {
|
||||||
|
return firstByte and 0xE0 == 0xC0
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val TAG = "HttpRequest";
|
private val TAG = "HttpRequest";
|
||||||
private val statusCodeMap = mapOf(
|
private val statusCodeMap = mapOf(
|
||||||
|
|
|
@ -5,8 +5,7 @@ import com.futo.platformplayer.api.http.ManagedHttpClient
|
||||||
import com.futo.platformplayer.api.http.server.exceptions.EmptyRequestException
|
import com.futo.platformplayer.api.http.server.exceptions.EmptyRequestException
|
||||||
import com.futo.platformplayer.api.http.server.handlers.HttpFuntionHandler
|
import com.futo.platformplayer.api.http.server.handlers.HttpFuntionHandler
|
||||||
import com.futo.platformplayer.api.http.server.handlers.HttpHandler
|
import com.futo.platformplayer.api.http.server.handlers.HttpHandler
|
||||||
import java.io.BufferedReader
|
import java.io.BufferedInputStream
|
||||||
import java.io.InputStreamReader
|
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
@ -76,12 +75,12 @@ class ManagedHttpServer(private val _requestedPort: Int = 0) {
|
||||||
|
|
||||||
private fun handleClientRequest(socket: Socket) {
|
private fun handleClientRequest(socket: Socket) {
|
||||||
_workerPool?.submit {
|
_workerPool?.submit {
|
||||||
val requestReader = BufferedReader(InputStreamReader(socket.getInputStream()))
|
val requestStream = BufferedInputStream(socket.getInputStream());
|
||||||
val responseStream = socket.getOutputStream();
|
val responseStream = socket.getOutputStream();
|
||||||
|
|
||||||
val requestId = UUID.randomUUID().toString().substring(0, 5);
|
val requestId = UUID.randomUUID().toString().substring(0, 5);
|
||||||
try {
|
try {
|
||||||
keepAliveLoop(requestReader, responseStream, requestId) { req ->
|
keepAliveLoop(requestStream, responseStream, requestId) { req ->
|
||||||
req.use { httpContext ->
|
req.use { httpContext ->
|
||||||
if(!httpContext.path.startsWith("/plugin/"))
|
if(!httpContext.path.startsWith("/plugin/"))
|
||||||
Logger.i(TAG, "[${req.id}] ${httpContext.method}: ${httpContext.path}")
|
Logger.i(TAG, "[${req.id}] ${httpContext.method}: ${httpContext.path}")
|
||||||
|
@ -107,7 +106,7 @@ class ManagedHttpServer(private val _requestedPort: Int = 0) {
|
||||||
Logger.e(TAG, "Failed to handle client request.", e);
|
Logger.e(TAG, "Failed to handle client request.", e);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
requestReader.close();
|
requestStream.close();
|
||||||
responseStream.close();
|
responseStream.close();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -188,7 +187,7 @@ class ManagedHttpServer(private val _requestedPort: Int = 0) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun keepAliveLoop(requestReader: BufferedReader, responseStream: OutputStream, requestId: String, handler: (HttpContext)->Unit) {
|
private fun keepAliveLoop(requestReader: BufferedInputStream, responseStream: OutputStream, requestId: String, handler: (HttpContext)->Unit) {
|
||||||
val stopCount = _stopCount;
|
val stopCount = _stopCount;
|
||||||
var keepAlive = false;
|
var keepAlive = false;
|
||||||
var requestsMax = 0;
|
var requestsMax = 0;
|
||||||
|
@ -200,7 +199,7 @@ class ManagedHttpServer(private val _requestedPort: Int = 0) {
|
||||||
handler(req);
|
handler(req);
|
||||||
|
|
||||||
requestsTotal++;
|
requestsTotal++;
|
||||||
if(req.keepAlive){// && requestReader.ready()) {
|
if(req.keepAlive) {
|
||||||
keepAlive = true;
|
keepAlive = true;
|
||||||
if(req.keepAliveMax > 0)
|
if(req.keepAliveMax > 0)
|
||||||
requestsMax = req.keepAliveMax;
|
requestsMax = req.keepAliveMax;
|
||||||
|
|
|
@ -301,7 +301,7 @@ class DeveloperEndpoints(private val context: Context) {
|
||||||
if(method != "isLoggedIn")
|
if(method != "isLoggedIn")
|
||||||
Logger.i(TAG, "Remote Call [${objId}].${method}(...)");
|
Logger.i(TAG, "Remote Call [${objId}].${method}(...)");
|
||||||
|
|
||||||
val parameters = context.readContentString(); //TODO: Temporary
|
val parameters = context.readContentString();
|
||||||
|
|
||||||
val remoteObj = getRemoteObject(objId);
|
val remoteObj = getRemoteObject(objId);
|
||||||
val paras = JsonParser.parseString(parameters);
|
val paras = JsonParser.parseString(parameters);
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.futo.platformplayer.stores.db
|
||||||
|
|
||||||
|
class ManagedDBIndex {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.futo.platformplayer.stores.db
|
||||||
|
|
||||||
|
class ManagedDBStore {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue