Handle rate limits
This commit is contained in:
@@ -8,16 +8,14 @@ import be.mygod.vpnhotspot.R
|
|||||||
import be.mygod.vpnhotspot.net.MacAddressCompat
|
import be.mygod.vpnhotspot.net.MacAddressCompat
|
||||||
import be.mygod.vpnhotspot.room.AppDatabase
|
import be.mygod.vpnhotspot.room.AppDatabase
|
||||||
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
import be.mygod.vpnhotspot.widget.SmartSnackbar
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.HttpURLConnection
|
import java.net.HttpURLConnection
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class generates a default nickname for new clients.
|
* This class generates a default nickname for new clients.
|
||||||
@@ -30,21 +28,32 @@ object MacLookup {
|
|||||||
override fun getLocalizedMessage() = formatMessage(app)
|
override fun getLocalizedMessage() = formatMessage(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val macLookupBusy = mutableMapOf<MacAddressCompat, Pair<HttpURLConnection, Job>>()
|
private data class Work(@Volatile var conn: HttpURLConnection, var job: Job? = null)
|
||||||
|
private val macLookupBusy = mutableMapOf<MacAddressCompat, Work>()
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
fun abort(mac: MacAddressCompat) = macLookupBusy.remove(mac)?.let { (conn, job) ->
|
fun abort(mac: MacAddressCompat) = macLookupBusy.remove(mac)?.let { work ->
|
||||||
job.cancel()
|
work.job!!.cancel()
|
||||||
if (Build.VERSION.SDK_INT >= 26) conn.disconnect() else GlobalScope.launch(Dispatchers.IO) { conn.disconnect() }
|
if (Build.VERSION.SDK_INT < 26) GlobalScope.launch(Dispatchers.IO) {
|
||||||
|
work.conn.disconnect()
|
||||||
|
} else work.conn.disconnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
fun perform(mac: MacAddressCompat, explicit: Boolean = false) {
|
fun perform(mac: MacAddressCompat, explicit: Boolean = false) {
|
||||||
abort(mac)
|
abort(mac)
|
||||||
val conn = URL("https://api.maclookup.app/v2/macs/${mac.toOui()}").openConnection() as HttpURLConnection
|
val url = URL("https://api.maclookup.app/v2/macs/${mac.toOui()}")
|
||||||
macLookupBusy[mac] = conn to GlobalScope.launch(Dispatchers.IO) {
|
val work = Work(url.openConnection() as HttpURLConnection)
|
||||||
|
work.job = GlobalScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
val response = conn.inputStream.bufferedReader().readText()
|
while (work.conn.responseCode != 200) {
|
||||||
|
if (work.conn.responseCode != 429) {
|
||||||
|
throw UnexpectedError(mac, work.conn.inputStream.bufferedReader().readText())
|
||||||
|
}
|
||||||
|
work.conn = url.openConnection() as HttpURLConnection
|
||||||
|
delay(max(1, work.conn.getHeaderField("Retry-After").toLongOrNull() ?: 1) * 1000)
|
||||||
|
}
|
||||||
|
val response = work.conn.inputStream.bufferedReader().readText()
|
||||||
val obj = JSONObject(response)
|
val obj = JSONObject(response)
|
||||||
if (!obj.getBoolean("success")) throw UnexpectedError(mac, response)
|
if (!obj.getBoolean("success")) throw UnexpectedError(mac, response)
|
||||||
if (!obj.getBoolean("found")) {
|
if (!obj.getBoolean("found")) {
|
||||||
@@ -70,5 +79,6 @@ object MacLookup {
|
|||||||
if (explicit) SmartSnackbar.make(e).show()
|
if (explicit) SmartSnackbar.make(e).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
macLookupBusy[mac] = work
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user