Refactor endpoints

This commit is contained in:
2020-07-02 22:59:15 +02:00
parent 0eb71bcb8e
commit 699136d640
4 changed files with 52 additions and 64 deletions

View File

@@ -75,7 +75,8 @@ class EndpointLoader(
private fun parseEnabled(luaTable: LuaTable) = luaTable.get("enabled").optboolean(true) private fun parseEnabled(luaTable: LuaTable) = luaTable.get("enabled").optboolean(true)
private fun parseAccepts(luaTable: LuaTable) = luaTable.get("accepts").optjstring("text/plain") private fun parseAccepts(luaTable: LuaTable) = luaTable.get("accepts").optjstring("")
.takeIf { it.isNotBlank() }
private fun parseQueued(luaTable: LuaTable) = luaTable.get("queued").optboolean(false) private fun parseQueued(luaTable: LuaTable) = luaTable.get("queued").optboolean(false)

View File

@@ -0,0 +1,30 @@
package com.bartlomiejpluta.ttsserver.core.web.endpoint
import com.bartlomiejpluta.ttsserver.core.web.dto.Request
import com.bartlomiejpluta.ttsserver.core.web.uri.UriTemplate
import fi.iki.elonen.NanoHTTPD
abstract class AbstractEndpoint(
protected val uri: UriTemplate,
protected val accepts: String?,
protected val method: NanoHTTPD.Method
) : Endpoint {
override fun hit(session: NanoHTTPD.IHTTPSession): NanoHTTPD.Response? {
if (session.method != method) {
return null
}
if (accepts?.let { it != session.headers["content-type"] } == true) {
return null
}
val matchingResult = uri.match(session.uri)
if (!matchingResult.matched) {
return null
}
return safeHit(Request.of(session, matchingResult))
}
abstract fun safeHit(request: Request): NanoHTTPD.Response?
}

View File

@@ -3,46 +3,24 @@ package com.bartlomiejpluta.ttsserver.core.web.endpoint
import com.bartlomiejpluta.ttsserver.core.web.dto.Request import com.bartlomiejpluta.ttsserver.core.web.dto.Request
import com.bartlomiejpluta.ttsserver.core.web.uri.UriTemplate import com.bartlomiejpluta.ttsserver.core.web.uri.UriTemplate
import fi.iki.elonen.NanoHTTPD.* import fi.iki.elonen.NanoHTTPD.*
import org.luaj.vm2.LuaClosure import org.luaj.vm2.*
import org.luaj.vm2.LuaNil
import org.luaj.vm2.LuaTable
import org.luaj.vm2.LuaValue
import java.io.BufferedInputStream import java.io.BufferedInputStream
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
class DefaultEndpoint( class DefaultEndpoint(
private val uri: UriTemplate, uri: UriTemplate,
private val accepts: String, accepts: String?,
private val method: Method, method: Method,
private val consumer: LuaClosure private val consumer: LuaClosure
) : Endpoint { ) : AbstractEndpoint(uri, accepts, method) {
override fun hit(session: IHTTPSession): Response? { override fun safeHit(request: Request) = request.luaTable
if (session.method != method) { .let { consumer.call(it) }
return null .checktable()
} .let { parseResponse(it) }
if ((session.headers["content-type"]?.let { it != accepts } != false)) { private fun parseResponse(response: LuaValue) = response.checktable()
return null
}
val matchingResult = uri.match(session.uri)
if (!matchingResult.matched) {
return null
}
val request = Request.of(session, matchingResult)
val response = consumer.call(request.luaTable).checktable()
return parseResponse(response)
}
private fun parseResponse(response: LuaValue) = response
.let {
it as? LuaTable
?: throw IllegalArgumentException("Invalid type for response - expected table")
}
.let { provideResponse(it) } .let { provideResponse(it) }
@@ -59,7 +37,7 @@ class DefaultEndpoint(
) )
private fun getFileResponse(response: LuaTable): Response? { private fun getFileResponse(response: LuaTable): Response? {
val file = File(response.get("file").checkstring().tojstring()) val file = File(response.get("file").checkjstring())
val stream = BufferedInputStream(FileInputStream(file)) val stream = BufferedInputStream(FileInputStream(file))
val length = file.length() val length = file.length()
return newFixedLengthResponse( return newFixedLengthResponse(
@@ -71,16 +49,16 @@ class DefaultEndpoint(
} }
private fun getStatus(response: LuaTable): Response.Status { private fun getStatus(response: LuaTable): Response.Status {
val status = response.get("status").checkint() val status = response.get("status").optint(Response.Status.OK.requestStatus)
return Response.Status return Response.Status
.values() .values()
.firstOrNull { it.requestStatus == status } .firstOrNull { it.requestStatus == status }
?: throw IllegalArgumentException("Unsupported status: $status") ?: throw LuaError("Unsupported status: $status")
} }
private fun getMimeType(response: LuaTable) = response.get("mime").checkstring().tojstring() private fun getMimeType(response: LuaTable) = response.get("mime").optjstring("text/plain")
private fun getData(response: LuaTable) = response.get("data").checkstring().tojstring() private fun getData(response: LuaTable) = response.get("data").checkjstring()
override fun toString() = "D[${uri.template}]" override fun toString() = "D[${uri.template}]"
} }

View File

@@ -9,11 +9,11 @@ import org.luaj.vm2.LuaClosure
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
class QueuedEndpoint( class QueuedEndpoint(
private val uri: UriTemplate, uri: UriTemplate,
private val accepts: String, accepts: String?,
private val method: NanoHTTPD.Method, method: NanoHTTPD.Method,
consumer: LuaClosure consumer: LuaClosure
) : Endpoint { ) : AbstractEndpoint(uri, accepts, method) {
private val queue = LinkedBlockingQueue<Request>() private val queue = LinkedBlockingQueue<Request>()
private val worker = Thread( private val worker = Thread(
Worker( Worker(
@@ -22,34 +22,13 @@ class QueuedEndpoint(
) )
).also { it.name = uri.template } ).also { it.name = uri.template }
override fun hit(session: NanoHTTPD.IHTTPSession): NanoHTTPD.Response? {
if (session.method != method) {
return null
}
if ((session.headers["content-type"]?.let { it != accepts } != false)) {
return null
}
val matchingResult = uri.match(session.uri)
if (!matchingResult.matched) {
return null
}
val request = Request.of(session, matchingResult)
override fun safeHit(request: Request): NanoHTTPD.Response? {
queue.add(request) queue.add(request)
return newFixedLengthResponse(NanoHTTPD.Response.Status.ACCEPTED, "text/plain", "") return newFixedLengthResponse(NanoHTTPD.Response.Status.ACCEPTED, "text/plain", "")
} }
private fun extractBody(session: NanoHTTPD.IHTTPSession): String {
return mutableMapOf<String, String>().let {
session.parseBody(it)
it["postData"] ?: ""
}
}
fun runWorker() = worker.start() fun runWorker() = worker.start()
fun stopWorker() = worker.interrupt() fun stopWorker() = worker.interrupt()