Skip to content

Commit

Permalink
Kotlin DefaultPacketSender
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesa2 committed Jul 11, 2024
1 parent 8ab31c9 commit d6c06ba
Show file tree
Hide file tree
Showing 7 changed files with 164 additions and 175 deletions.

This file was deleted.

140 changes: 140 additions & 0 deletions tracker/src/main/java/org/matomo/sdk/dispatcher/DefaultPacketSender.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package org.matomo.sdk.dispatcher

import org.matomo.sdk.Matomo.Companion.tag
import timber.log.Timber
import java.io.BufferedReader
import java.io.BufferedWriter
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.InputStreamReader
import java.io.OutputStream
import java.io.OutputStreamWriter
import java.net.HttpURLConnection
import java.net.URL
import java.nio.charset.StandardCharsets
import java.util.zip.GZIPOutputStream

class DefaultPacketSender : PacketSender {
private var mTimeout = Dispatcher.DEFAULT_CONNECTION_TIMEOUT.toLong()
private var mGzip = false

override fun send(packet: Packet): Boolean {
var urlConnection: HttpURLConnection? = null
try {
urlConnection = URL(packet.targetURL).openConnection() as HttpURLConnection

Timber.tag(TAG).v("Connection is open to %s", urlConnection.url.toExternalForm())
Timber.tag(TAG).v("Sending: %s", packet)

urlConnection.connectTimeout = mTimeout.toInt()
urlConnection.readTimeout = mTimeout.toInt()

// IF there is json data we have to do a post
if (packet.postData != null) { // POST
urlConnection.doOutput = true // Forces post
urlConnection.setRequestProperty("Content-Type", "application/json")
urlConnection.setRequestProperty("charset", "utf-8")

val toPost = packet.postData.toString()
if (mGzip) {
urlConnection.addRequestProperty("Content-Encoding", "gzip")
val byteArrayOS = ByteArrayOutputStream()

GZIPOutputStream(byteArrayOS).use { gzipStream ->
gzipStream.write(toPost.toByteArray(StandardCharsets.UTF_8))
}
// If closing fails we assume the written data to be invalid.
// Don't catch the exception and let it abort the `send(Packet)` call.
var outputStream: OutputStream? = null
try {
outputStream = urlConnection.outputStream
outputStream.write(byteArrayOS.toByteArray())
} finally {
if (outputStream != null) {
try {
outputStream.close()
} catch (e: IOException) {
// Failing to close the stream is not enough to consider the transmission faulty.
Timber.tag(TAG).d(e, "Failed to close output stream after writing gzipped POST data.")
}
}
}
} else {
var writer: BufferedWriter? = null
try {
writer = BufferedWriter(OutputStreamWriter(urlConnection.outputStream, StandardCharsets.UTF_8))
writer.write(toPost)
} finally {
if (writer != null) {
try {
writer.close()
} catch (e: IOException) {
// Failing to close the stream is not enough to consider the transmission faulty.
Timber.tag(TAG).d(e, "Failed to close output stream after writing POST data.")
}
}
}
}
} else { // GET
urlConnection.doOutput = false // Defaults to false, but for readability
}

val statusCode = urlConnection.responseCode
Timber.tag(TAG).v("Transmission finished (code=%d).", statusCode)
val successful = checkResponseCode(statusCode)

if (successful) {
// https://github.com/matomo-org/matomo-sdk-android/issues/226

val `is` = urlConnection.inputStream
if (`is` != null) {
try {
`is`.close()
} catch (e: IOException) {
Timber.tag(TAG).d(e, "Failed to close the error stream.")
}
}
} else {
// Consume the error stream (or at least close it) if the status code was non-OK (not 2XX)
val errorReason = StringBuilder()
var errorReader: BufferedReader? = null
try {
errorReader = BufferedReader(InputStreamReader(urlConnection.errorStream))
var line: String?
while ((errorReader.readLine().also { line = it }) != null) errorReason.append(line)
} finally {
if (errorReader != null) {
try {
errorReader.close()
} catch (e: IOException) {
Timber.tag(TAG).d(e, "Failed to close the error stream.")
}
}
}
Timber.tag(TAG).w("Transmission failed (code=%d, reason=%s)", statusCode, errorReason.toString())
}

return successful
} catch (e: Exception) {
Timber.tag(TAG).e(e, "Transmission failed unexpectedly.")
return false
} finally {
urlConnection?.disconnect()
}
}

override fun setTimeout(timeout: Long) {
mTimeout = timeout
}

override fun setGzipData(gzip: Boolean) {
mGzip = gzip
}

companion object {
private val TAG = tag(DefaultPacketSender::class.java)
private fun checkResponseCode(code: Int): Boolean {
return code == HttpURLConnection.HTTP_NO_CONTENT || code == HttpURLConnection.HTTP_OK
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.matomo.sdk.dispatcher

import org.matomo.sdk.Tracker

interface DispatcherFactory {
fun build(tracker: Tracker?): Dispatcher?
}
16 changes: 0 additions & 16 deletions tracker/src/main/java/org/matomo/sdk/dispatcher/PacketSender.java

This file was deleted.

16 changes: 16 additions & 0 deletions tracker/src/main/java/org/matomo/sdk/dispatcher/PacketSender.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.matomo.sdk.dispatcher


interface PacketSender {
/**
* @return true if successful
*/
fun send(packet: Packet?): Boolean

/**
* @param timeout in milliseconds
*/
fun setTimeout(timeout: Long)

fun setGzipData(gzip: Boolean)
}
2 changes: 1 addition & 1 deletion tracker/src/main/java/org/matomo/sdk/tools/UrlHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class UrlHelper {
public static List<Pair<String, String>> parse(@NonNull final URI uri, @Nullable final String encoding) {
List<Pair<String, String>> result = Collections.emptyList();
final String query = uri.getRawQuery();
if (query != null && query.length() > 0) {
if (query != null && !query.isEmpty()) {
result = new ArrayList<>();
parse(result, new Scanner(query), encoding);
}
Expand Down

0 comments on commit d6c06ba

Please sign in to comment.