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 = 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") } }