Last active
December 26, 2022 01:51
-
-
Save hotstu/ce655e592792bed8e4e6dc1c89b2addc to your computer and use it in GitHub Desktop.
NanoHttpd wrapper for jsonrpc4j
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.google.gson.Gson | |
import com.googlecode.jsonrpc4j.JsonRpcBasicServer.* | |
import com.googlecode.jsonrpc4j.JsonRpcServer | |
import fi.iki.elonen.NanoHTTPD | |
import java.io.ByteArrayInputStream | |
import java.io.ByteArrayOutputStream | |
import java.io.IOException | |
import java.io.InputStream | |
import java.nio.charset.StandardCharsets | |
class Server( | |
private val services: Map<String, JsonRpcServer>, | |
private val desc: Map<String, String>, | |
host: String, | |
port: Int | |
) : NanoHTTPD(host, port) { | |
val mapper = Gson() | |
override fun serve(session: IHTTPSession): Response { | |
val uri = session.uri | |
println("${session.remoteIpAddress}<---$uri") | |
if (uri == "/") { | |
return newFixedLengthResponse( | |
Response.Status.OK, | |
"text/json", | |
mapper.toJson(desc) | |
) | |
} | |
var model = uri | |
if (model.startsWith("/")) { | |
model = model.substring(1) | |
} | |
if (model.contains("/")) { | |
model = model.substring(0, model.lastIndexOf("/")) | |
} | |
val rpc = services.get(model) | |
?: return newFixedLengthResponse( | |
Response.Status.NOT_FOUND, | |
"text/json", | |
"{\"error\": \"访问的服务不存在\"}", | |
) | |
return if (session.method == Method.POST) { | |
val input: InputStream = session.inputStream | |
val output: ByteArrayOutputStream = ByteArrayOutputStream() | |
rpc.handleRequest(input, output) | |
val byteArrayInputStream = ByteArrayInputStream(output.toByteArray()) | |
return newFixedLengthResponse( | |
Response.Status.OK, | |
"text/json", | |
byteArrayInputStream, | |
byteArrayInputStream.available().toLong() | |
) | |
} else if (session.method == Method.GET) { | |
val parameters = session.parms | |
val input: InputStream = | |
createInputStream(parameters[METHOD], parameters[ID], parameters[PARAMS]) | |
val output: ByteArrayOutputStream = ByteArrayOutputStream() | |
rpc.handleRequest(input, output) | |
val byteArrayInputStream = ByteArrayInputStream(output.toByteArray()) | |
return newFixedLengthResponse( | |
Response.Status.OK, | |
"text/json", | |
byteArrayInputStream, | |
byteArrayInputStream.available().toLong() | |
) | |
} else { | |
throw IOException("Invalid request method, only POST and GET is supported") | |
} | |
} | |
companion object { | |
/** | |
* Returns parameters into an [InputStream] of JSON data. | |
* | |
* @param method the method | |
* @param id the id | |
* @param params the base64 encoded params | |
* @return the [InputStream] | |
* @throws IOException on error | |
*/ | |
fun createInputStream(method: String?, id: String?, params: String?): InputStream { | |
val envelope = StringBuilder() | |
envelope.append("{\"") | |
envelope.append(JSONRPC) | |
envelope.append("\":\"") | |
envelope.append(VERSION) | |
envelope.append("\",\"") | |
envelope.append(ID) | |
envelope.append("\":") | |
// the 'id' value is assumed to be numerical. | |
if (null != id && !id.isEmpty()) { | |
envelope.append(id) | |
} else { | |
envelope.append("null") | |
} | |
envelope.append(",\"") | |
envelope.append(METHOD) | |
envelope.append("\":") | |
if (null != method && !method.isEmpty()) { | |
envelope.append('"') | |
envelope.append(method) | |
envelope.append('"') | |
} else { | |
envelope.append("null") | |
} | |
envelope.append(",\"") | |
envelope.append(PARAMS) | |
envelope.append("\":") | |
if (null != params && !params.isEmpty()) { | |
val decodedParams = when (params[0]) { | |
'[', '{' -> params | |
else -> throw IOException("badly formed 'param' parameter starting with; [" + params[0] + "]") | |
} | |
envelope.append(decodedParams) | |
} else { | |
envelope.append("[]") | |
} | |
envelope.append('}') | |
return ByteArrayInputStream(envelope.toString().toByteArray(StandardCharsets.UTF_8)) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment