Skip to content

Commit

Permalink
Generalized HTTP Network Layer (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
Funkatronics authored Nov 18, 2022
1 parent b3c2e9c commit a426a7b
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 29 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* NetworkDriver
* metaplex-android
*
* Created by Funkatronics on 11/6/2022
*/

package com.metaplex.lib.drivers.network

interface HttpNetworkDriver {
suspend fun makeHttpRequest(request: HttpRequest): String
}
41 changes: 41 additions & 0 deletions lib/src/main/java/com/metaplex/lib/drivers/network/HttpRequest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* HttpRequest
* metaplex-android
*
* Created by Funkatronics on 11/6/2022
*/

package com.metaplex.lib.drivers.network

enum class HttpMethod(name: String){
GET("GET"),
POST("POST"),
HEAD("HEAD"),
OPTIONS("OPTIONS"),
PUT("PUT"),
DELETE("DELETE"),
TRACE("TRACE")
}

interface HttpRequest {
val url: String
val method: String
val properties: Map<String, String>
val body: String?
}

class HttpGetRequest(
override val url: String,
override val properties: Map<String, String>
) : HttpRequest {
override val method = HttpMethod.GET.name
override val body = null
}

class HttpPostRequest(
override val url: String,
override val properties: Map<String, String>,
override val body: String? = null
) : HttpRequest {
override val method = HttpMethod.POST.name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* JdkHttpDriver
* metaplex-android
*
* Created by Funkatronics on 11/6/2022
*/

package com.metaplex.lib.drivers.network

import kotlinx.coroutines.suspendCancellableCoroutine
import java.net.HttpURLConnection
import java.net.URL

/**
* A [HttpNetworkDriver] implementation using the native JDK [HttpURLConnection]
*
* @see HttpNetworkDriver
* @see java.net.HttpURLConnection
*
* @author Funkatronics
*/
class JdkHttpDriver : HttpNetworkDriver {
override suspend fun makeHttpRequest(request: HttpRequest): String =
suspendCancellableCoroutine { continuation ->

with(URL(request.url).openConnection() as HttpURLConnection) {
// config
requestMethod = request.method
request.properties.forEach { (key, value) ->
setRequestProperty(key, value)
}

// cancellation
continuation.invokeOnCancellation { disconnect() }

// send request body
request.body?.run {
doOutput = true
outputStream.write(toByteArray(Charsets.UTF_8))
outputStream.flush()
outputStream.close()
}

// read response
val responseString = inputStream.bufferedReader().use { it.readText() }

// TODO: should check response code and/or errorStream for errors
// println("URL : $url")
// println("Response Code : $responseCode")
// println("input stream : $responseString")

continuation.resumeWith(Result.success(responseString))
}
}
}
42 changes: 13 additions & 29 deletions lib/src/main/java/com/metaplex/lib/drivers/rpc/JdkRpcDriver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

package com.metaplex.lib.drivers.rpc

import kotlinx.coroutines.suspendCancellableCoroutine
import com.metaplex.lib.drivers.network.HttpPostRequest
import com.metaplex.lib.drivers.network.JdkHttpDriver
import kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json
import java.net.HttpURLConnection
Expand All @@ -21,40 +22,23 @@ import java.net.URL
*
* @author Funkatronics
*/
class JdkRpcDriver(val url: URL) : JsonRpcDriver {
class JdkRpcDriver(val url: String) : JsonRpcDriver {

constructor(url: URL) : this(url.toString())

private val json = Json {
encodeDefaults = true
ignoreUnknownKeys = true
}

override suspend fun <R> makeRequest(request: RpcRequest, resultSerializer: KSerializer<R>): RpcResponse<R> =
suspendCancellableCoroutine { continuation ->

with(url.openConnection() as HttpURLConnection) {
// config
setRequestProperty("Content-Type", "application/json; charset=utf-8")
requestMethod = "POST"
doOutput = true

// cancellation
continuation.invokeOnCancellation { disconnect() }

// send request body
outputStream.write(json.encodeToString(RpcRequest.serializer(), request).toByteArray())
outputStream.close()

// read response
val responseString = inputStream.bufferedReader().use { it.readText() }

// TODO: should check response code and/or errorStream for errors
// println("URL : $url")
// println("Response Code : $responseCode")
// println("input stream : $responseString")

continuation.resumeWith(Result.success(
json.decodeFromString(RpcResponse.serializer(resultSerializer), responseString)
))
JdkHttpDriver().makeHttpRequest(
HttpPostRequest(
url = url,
properties = mapOf("Content-Type" to "application/json; charset=utf-8"),
body = json.encodeToString(RpcRequest.serializer(), request)
)
).run {
json.decodeFromString(RpcResponse.serializer(resultSerializer), this)
}
}
}

0 comments on commit a426a7b

Please sign in to comment.