4
4
5
5
package org.equeim.tremotesf.torrentfile.rpc.requests
6
6
7
- import android.net.Uri
8
7
import kotlinx.serialization.Contextual
9
8
import kotlinx.serialization.ExperimentalSerializationApi
10
9
import kotlinx.serialization.KSerializer
@@ -29,6 +28,9 @@ import org.equeim.tremotesf.torrentfile.rpc.RpcClient
29
28
import org.equeim.tremotesf.torrentfile.rpc.RpcRequestContext
30
29
import org.equeim.tremotesf.torrentfile.rpc.RpcRequestError
31
30
import org.threeten.bp.Instant
31
+ import timber.log.Timber
32
+ import java.net.URI
33
+ import java.net.URISyntaxException
32
34
import java.util.concurrent.ConcurrentHashMap
33
35
import kotlin.time.Duration
34
36
@@ -180,10 +182,18 @@ private object TrackerSitesSerializer : JsonTransformingSerializer<List<String>>
180
182
return JsonArray (element.jsonArray.map { arrayElement ->
181
183
val announceUrl = arrayElement.jsonObject.getValue(" announce" ).jsonPrimitive
182
184
cache.getOrPut(announceUrl) {
183
- // We can't convert announceUrl to HttpUtl directly since announce URLs may have udp:// scheme
185
+ // We can't convert announceUrl to HttpUrl directly since announce URLs may have udp:// scheme
184
186
// and HttpUrl supports only http:// and https://
185
- // Extract host using Uri and construct fake HttpUrl using http:// scheme instead
186
- Uri .parse(announceUrl.content).host?.let { host ->
187
+ // Extract host using URI and construct fake HttpUrl using http:// scheme instead
188
+ // android.net.Uri incorrectly parses URL wit IPv6 addresses on older Android versions,
189
+ // so we use java.net.URI which works
190
+ val uri = try {
191
+ URI (announceUrl.content)
192
+ } catch (e: URISyntaxException ) {
193
+ Timber .e(e, " Failed to parse URI from ${announceUrl.content} " )
194
+ null
195
+ }
196
+ uri?.host?.let { host ->
187
197
JsonPrimitive (HttpUrl .Builder ().scheme(" http" ).host(host).build().topPrivateDomain() ? : host)
188
198
} ? : announceUrl
189
199
}
0 commit comments