ariane/app/src/main/java/oppen/tva/io/GeminiDatasource.kt

91 lines
2.7 KiB
Kotlin

package oppen.tva.io
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.*
import java.net.URI
import java.security.SecureRandom
import javax.net.ssl.*
const val GEMINI_SCHEME = "gemini"
class GeminiDatasource: Datasource{
override fun request(uri: URI, onUpdate: (state: TvaState) -> Unit) {
//Any inputted uri starting with a colon is an app-specific command, eg. :prefs :settings
if(uri.toString().startsWith(":")){
onUpdate(TvaState.AppQuery(uri))
return
}
when (uri.scheme) {
GEMINI_SCHEME -> {
//Indicate app should show progress indicator
onUpdate(TvaState.Requesting(uri))
GlobalScope.launch {
geminiRequest(uri, onUpdate)
}
}
else -> onUpdate(TvaState.NotGeminiRequest(uri))
}
}
/**
*
* This was largely copied from https://framagit.org/waweic/gemini-client/-/blob/master/app/src/main/java/rocks/ism/decentral/geminiclient/GeminiConnection.kt
*
*/
private fun geminiRequest(uri: URI, onUpdate: (state: TvaState) -> Unit){
val port = if(uri.port == -1) 1965 else uri.port
val sslContext = SSLContext.getInstance("TLSv1.2")
sslContext.init(null, DummyTrustManager.get(), SecureRandom())
val factory: SSLSocketFactory = sslContext.socketFactory
val socket: SSLSocket = factory.createSocket(uri.host, port) as SSLSocket
socket.enabledProtocols = arrayOf("TLSv1.2")
socket.startHandshake()
// OUT >>>>>>>>>>>>>>>>>>>>>>>>>>
val outputStreamWriter = OutputStreamWriter(socket.outputStream)
val bufferedWriter = BufferedWriter(outputStreamWriter)
val outWriter = PrintWriter(bufferedWriter)
outWriter.print(uri.toString() + "\r\n")
outWriter.flush()
if (outWriter.checkError()) {
onUpdate(TvaState.GeminiPrintWriterError)
outWriter.close()
return
}
// IN <<<<<<<<<<<<<<<<<<<<<<<<<<<
val lines = mutableListOf<String>()
socket.inputStream.reader().use { inputStreamReader ->
BufferedReader(inputStreamReader).use { reader ->
lines.addAll(reader.readLines())
}
}
val header = lines.firstOrNull() ?: ""
lines.removeAt(0)
println("Tva: header: $header")
lines.forEach {
println("Tva: line: $it")
}
println("Tva: ends -----------------")
outputStreamWriter.close()
bufferedWriter.close()
outWriter.close()
onUpdate(TvaState.GeminiResponse(uri, header, lines))
}
}