Files
Cobblesync/src/main/kotlin/co/sirblob/Request.kt
2025-06-05 14:13:24 -04:00

137 lines
5.0 KiB
Kotlin

package co.sirblob
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.IOException
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URI
import java.net.URL
import java.nio.charset.StandardCharsets
import org.json.JSONObject
class Request(baseUrl: String) {
var baseUrl: String = baseUrl
private set
private val headers: MutableMap<String, String> = mutableMapOf()
init {
this.addHeader("Accept", "*/*")
this.addHeader("Content-Type", "application/json; charset=utf-8")
}
fun setBaseUrl(url: String) {
this.baseUrl = url
}
fun addHeader(key: String, value: String) {
this.headers[key] = value
}
fun setHeader(key: String, value: String) {
this.headers[key] = value
}
fun removeHeader(key: String) {
this.headers.remove(key)
}
@Throws(HTTPException::class)
private fun generateResponse(responseCode: Int, responseBody: String): JSONObject {
return when (responseCode) {
HttpURLConnection.HTTP_OK -> {
if (responseBody.startsWith("{") || responseBody.startsWith("[")) {
JSONObject(responseBody).put("status", responseCode)
} else if (responseBody.isBlank()) {
JSONObject().put("status", responseCode)
} else {
JSONObject().put("data", responseBody).put("status", responseCode)
}
}
HttpURLConnection.HTTP_NO_CONTENT -> JSONObject().put("status", responseCode)
HttpURLConnection.HTTP_BAD_REQUEST -> throw HTTPException(responseCode, "Bad request")
HttpURLConnection.HTTP_UNAUTHORIZED -> throw HTTPException(responseCode, "Unauthorized")
HttpURLConnection.HTTP_FORBIDDEN -> throw HTTPException(responseCode, "Forbidden")
HttpURLConnection.HTTP_NOT_FOUND -> throw HTTPException(responseCode, "Not found")
HttpURLConnection.HTTP_INTERNAL_ERROR -> throw HTTPException(responseCode, "Internal server error")
else -> {
if (!responseBody.startsWith("{") && !responseBody.startsWith("[") && responseBody.isNotBlank()) {
JSONObject().put("data", responseBody).put("status", responseCode)
} else if (responseBody.startsWith("{") || responseBody.startsWith("[")) {
JSONObject(responseBody).put("status", responseCode)
}
else {
JSONObject().put("status", responseCode)
}
}
}
}
@Throws(IOException::class, HTTPException::class)
private fun performRequest(urlPath: String, method: String, requestBodyJson: JSONObject? = null): JSONObject {
val fullUrl = URI.create(baseUrl).resolve(urlPath).toURL()
val con = fullUrl.openConnection() as HttpURLConnection
try {
con.requestMethod = method
headers.forEach { (key, value) -> con.setRequestProperty(key, value) }
con.connectTimeout = 5000
con.readTimeout = 5000
if (requestBodyJson != null && (method == "POST" || method == "PUT" || method == "PATCH")) {
con.doOutput = true
val bodyBytes = requestBodyJson.toString().toByteArray(StandardCharsets.UTF_8)
con.setRequestProperty("Content-Length", bodyBytes.size.toString())
DataOutputStream(con.outputStream).use { outputStream ->
outputStream.write(bodyBytes)
outputStream.flush()
}
}
val responseCode = con.responseCode
val responseBody: String = try {
val streamToRead = if (responseCode < HttpURLConnection.HTTP_BAD_REQUEST) {
con.inputStream
} else {
con.errorStream
}
streamToRead?.bufferedReader(StandardCharsets.UTF_8)?.use { it.readText() } ?: ""
} catch (e: IOException) {
""
}
return generateResponse(responseCode, responseBody)
} finally {
con.disconnect()
}
}
@Throws(IOException::class, HTTPException::class)
fun GET(urlPath: String): JSONObject {
return performRequest(urlPath, "GET")
}
@Throws(IOException::class, HTTPException::class)
fun POST(urlPath: String, body: JSONObject): JSONObject {
return performRequest(urlPath, "POST", body)
}
@Throws(IOException::class, HTTPException::class)
fun PUT(urlPath: String, body: JSONObject): JSONObject {
return performRequest(urlPath, "PUT", body)
}
@Throws(IOException::class, HTTPException::class)
fun PATCH(urlPath: String, body: JSONObject): JSONObject {
return performRequest(urlPath, "PATCH", body)
}
@Throws(IOException::class, HTTPException::class)
fun DELETE(urlPath: String): JSONObject {
return performRequest(urlPath, "DELETE")
}
}