diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/MainRoute.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/MainRoute.kt index bacec9f..0e0a3c4 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/MainRoute.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/api/MainRoute.kt @@ -17,10 +17,12 @@ import moe.fuqiuluo.shamrock.remote.config.ECHO_KEY import moe.fuqiuluo.shamrock.remote.entries.EmptyObject import moe.fuqiuluo.shamrock.remote.entries.IndexData import moe.fuqiuluo.shamrock.remote.entries.Status +import moe.fuqiuluo.shamrock.tools.EmptyJsonObject import moe.fuqiuluo.shamrock.tools.fetchOrNull import moe.fuqiuluo.shamrock.tools.fetchOrThrow import moe.fuqiuluo.shamrock.tools.fetchPostJsonElement import moe.fuqiuluo.shamrock.tools.fetchPostJsonObject +import moe.fuqiuluo.shamrock.tools.fetchPostJsonObjectOrNull import moe.fuqiuluo.shamrock.tools.isJsonArray import moe.fuqiuluo.shamrock.tools.isJsonObject import moe.fuqiuluo.shamrock.tools.isJsonString @@ -55,7 +57,7 @@ fun Routing.echoVersion() { } call.attributes.put(ECHO_KEY, echo) - val params = fetchPostJsonObject("params") + val params = fetchPostJsonObjectOrNull("params") ?: EmptyJsonObject val handler = ActionManager[action] if (handler == null) { diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/WebSocketTransmitServlet.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/WebSocketTransmitServlet.kt index 44c0ffb..9377797 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/WebSocketTransmitServlet.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/remote/service/api/WebSocketTransmitServlet.kt @@ -97,7 +97,7 @@ internal abstract class WebSocketTransmitServlet( } val action = actionObject["action"].asString val echo = actionObject["echo"] ?: EmptyJsonString - val params = actionObject["params"].asJsonObject + val params = actionObject["params"].asJsonObjectOrNull ?: EmptyJsonObject val handler = ActionManager[action] handler?.handle(ActionSession(params, echo)) diff --git a/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/KtorServer.kt b/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/KtorServer.kt index c784070..625ef4c 100644 --- a/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/KtorServer.kt +++ b/xposed/src/main/java/moe/fuqiuluo/shamrock/tools/KtorServer.kt @@ -20,13 +20,10 @@ import kotlinx.serialization.json.JsonPrimitive import kotlinx.serialization.json.jsonObject import moe.fuqiuluo.shamrock.helper.ParamsException import io.ktor.http.HttpMethod -import io.ktor.http.decodeURLPart import io.ktor.http.parseUrlEncodedParameters import io.ktor.server.request.httpMethod import io.ktor.server.routing.route import kotlinx.serialization.json.JsonElement -import moe.fuqiuluo.shamrock.helper.Level -import moe.fuqiuluo.shamrock.helper.LogCenter import moe.fuqiuluo.shamrock.remote.entries.CommonResult import moe.fuqiuluo.shamrock.remote.entries.EmptyObject import moe.fuqiuluo.shamrock.remote.entries.Status @@ -38,9 +35,9 @@ import moe.fuqiuluo.shamrock.remote.entries.Status annotation class ShamrockDsl -private val isJsonKey = AttributeKey("isJson") -private val jsonKey = AttributeKey("paramsJson") -private val partsKey = AttributeKey("paramsParts") +private val keyIsJson = AttributeKey("isJson") +private val keyJsonObject = AttributeKey("paramsJson") +private val keyParts = AttributeKey("paramsParts") suspend fun ApplicationCall.fetch(key: String): String { val isPost = request.httpMethod == HttpMethod.Post @@ -94,23 +91,23 @@ fun ApplicationCall.isJsonData(): Boolean { } suspend fun ApplicationCall.fetchPostOrNull(key: String): String? { - if (attributes.contains(jsonKey)) { - return attributes[jsonKey][key].asStringOrNull + if (attributes.contains(keyJsonObject)) { + return attributes[keyJsonObject][key].asStringOrNull } - if (attributes.contains(partsKey)) { - return attributes[partsKey][key] + if (attributes.contains(keyParts)) { + return attributes[keyParts][key] } return kotlin.runCatching { if (isJsonData()) { Json.parseToJsonElement(receiveText()).jsonObject.also { - attributes.put(jsonKey, it) - attributes.put(isJsonKey, true) + attributes.put(keyJsonObject, it) + attributes.put(keyIsJson, true) }[key].asStringOrNull } else if ( ContentType.Application.FormUrlEncoded == request.contentType() ) { receiveParameters().also { - attributes.put(partsKey, it) + attributes.put(keyParts, it) }[key] } else { receiveTextAsUnknown(key) @@ -124,13 +121,13 @@ private suspend fun ApplicationCall.receiveTextAsUnknown(key: String): String? { return receiveText().let { text -> if (text.startsWith("{") && text.endsWith("}")) { Json.parseToJsonElement(text).jsonObject.also { - attributes.put(jsonKey, it) - attributes.put(isJsonKey, true) + attributes.put(keyJsonObject, it) + attributes.put(keyIsJson, true) }[key].asStringOrNull } else { text.parseUrlEncodedParameters().also { - attributes.put(partsKey, it) - attributes.put(isJsonKey, false) + attributes.put(keyParts, it) + attributes.put(keyIsJson, false) }[key] } } // receiveText @@ -170,17 +167,17 @@ suspend fun PipelineContext.fetchPostOrThrow(key: String) } fun PipelineContext.isJsonData(): Boolean { - return ContentType.Application.Json == call.request.contentType() || (isJsonKey in call.attributes && call.attributes[isJsonKey]) + return ContentType.Application.Json == call.request.contentType() || (keyIsJson in call.attributes && call.attributes[keyIsJson]) } suspend fun PipelineContext.isJsonString(key: String): Boolean { if (!isJsonData()) return true - val data = if (jsonKey in call.attributes) { - call.attributes[jsonKey] + val data = if (keyJsonObject in call.attributes) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) - call.attributes.put(isJsonKey, true) + call.attributes.put(keyJsonObject, it) + call.attributes.put(keyIsJson, true) } } return data[key] is JsonPrimitive @@ -188,11 +185,11 @@ suspend fun PipelineContext.isJsonString(key: String): Bo suspend fun PipelineContext.isJsonObject(key: String): Boolean { if (!isJsonData()) return false - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) + call.attributes.put(keyJsonObject, it) } } return data[key] is JsonObject @@ -200,56 +197,68 @@ suspend fun PipelineContext.isJsonObject(key: String): Bo suspend fun PipelineContext.isJsonArray(key: String): Boolean { if (!isJsonData()) return false - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) + call.attributes.put(keyJsonObject, it) } } return data[key] is JsonArray } suspend fun PipelineContext.fetchPostJsonString(key: String): String { - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) + call.attributes.put(keyJsonObject, it) } } return data[key].asString } suspend fun PipelineContext.fetchPostJsonElement(key: String): JsonElement { - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) + call.attributes.put(keyJsonObject, it) } } return data[key]!! } suspend fun PipelineContext.fetchPostJsonObject(key: String): JsonObject { - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) + call.attributes.put(keyJsonObject, it) } } return data[key].asJsonObject } -suspend fun PipelineContext.fetchPostJsonArray(key: String): JsonArray { - val data = if (call.attributes.contains(jsonKey)) { - call.attributes[jsonKey] +suspend fun PipelineContext.fetchPostJsonObjectOrNull(key: String): JsonObject? { + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] } else { Json.parseToJsonElement(call.receiveText()).jsonObject.also { - call.attributes.put(jsonKey, it) - call.attributes.put(isJsonKey, true) + call.attributes.put(keyJsonObject, it) + } + } + return data[key].asJsonObjectOrNull +} + + +suspend fun PipelineContext.fetchPostJsonArray(key: String): JsonArray { + val data = if (call.attributes.contains(keyJsonObject)) { + call.attributes[keyJsonObject] + } else { + Json.parseToJsonElement(call.receiveText()).jsonObject.also { + call.attributes.put(keyJsonObject, it) + call.attributes.put(keyIsJson, true) } } return data[key].asJsonArray