diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt index 7e17503ef0..306fd573bd 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt @@ -58,18 +58,21 @@ class InstrumentationApplicationDependencyProvider(val application: Application, Get("/v1/websocket/?login=") { MockResponse().success().withWebSocketUpgrade(mockIdentifiedWebSocket) }, - Get("/v1/websocket", { !it.path.contains("login") }) { + Get("/v1/websocket", { + val path = it.path + return@Get path == null || !path.contains("login") + }) { MockResponse().success().withWebSocketUpgrade(object : WebSocketListener() {}) } ) } - webServer.setDispatcher(object : Dispatcher() { + webServer.dispatcher = object : Dispatcher() { override fun dispatch(request: RecordedRequest): MockResponse { val handler = handlers.firstOrNull { it.requestPredicate(request) } return handler?.responseFactory?.invoke(request) ?: MockResponse().setResponseCode(500) } - }) + } serviceTrustStore = SignalServiceTrustStore(application) uncensoredConfiguration = SignalServiceConfiguration( diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/ResponseMocking.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/ResponseMocking.kt index 13268521da..3d3ca25567 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/testing/ResponseMocking.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/testing/ResponseMocking.kt @@ -55,5 +55,5 @@ inline fun RecordedRequest.parsedRequestBody(): T { } private fun defaultRequestPredicate(verb: String, path: String, predicate: RequestPredicate = { true }): RequestPredicate = { request -> - request.method == verb && request.path.startsWith("/$path") && predicate(request) + request.method == verb && request.path?.startsWith("/$path") == true && predicate(request) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt index b9d9af9a25..0f21358e9c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/ApkUpdateJob.kt @@ -67,10 +67,10 @@ class ApkUpdateJob private constructor(parameters: Parameters) : BaseJob(paramet val request = Request.Builder().url(BuildConfig.APK_UPDATE_MANIFEST_URL).build() val rawUpdateDescriptor: String = client.newCall(request).execute().use { response -> - if (!response.isSuccessful || response.body() == null) { + if (!response.isSuccessful || response.body == null) { throw IOException("Failed to read update descriptor") } - response.body()!!.string() + response.body!!.string() } val updateDescriptor: UpdateDescriptor = JsonUtils.fromJson(rawUpdateDescriptor, UpdateDescriptor::class.java) diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt index 50482b71ad..4ab9c0c040 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AttachmentDownloadJob.kt @@ -400,7 +400,7 @@ class AttachmentDownloadJob private constructor( ) { try { S3.getObject(attachment.fileName!!).use { response -> - val body = response.body() + val body = response.body if (body != null) { if (body.contentLength() > RemoteConfig.maxAttachmentReceiveSizeBytes) { throw MmsException("Attachment too large, failing download") diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/FetchRemoteMegaphoneImageJob.kt b/app/src/main/java/org/thoughtcrime/securesms/jobs/FetchRemoteMegaphoneImageJob.kt index 7e8e23660c..34ccbc9aca 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/FetchRemoteMegaphoneImageJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/FetchRemoteMegaphoneImageJob.kt @@ -42,7 +42,7 @@ class FetchRemoteMegaphoneImageJob(parameters: Parameters, private val uuid: Str override fun onRun() { try { S3.getObject(imageUrl).use { response -> - val body: ResponseBody? = response.body() + val body: ResponseBody? = response.body if (body != null) { val uri = BlobProvider.getInstance() .forData(body.byteStream(), body.contentLength()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/s3/S3.kt b/app/src/main/java/org/thoughtcrime/securesms/s3/S3.kt index c8c56e8aa1..53f5373e2c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/s3/S3.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/s3/S3.kt @@ -53,10 +53,10 @@ object S3 { fun getString(endpoint: String): String { getObject(endpoint).use { response -> if (!response.isSuccessful) { - throw NonSuccessfulResponseCodeException(response.code()) + throw NonSuccessfulResponseCodeException(response.code) } - return response.body()?.string()?.trim() ?: throw IOException() + return response.body?.string()?.trim() ?: throw IOException() } } @@ -110,13 +110,13 @@ object S3 { getObject(endpoint).use { response -> if (!response.isSuccessful) { return ServiceResponse.forApplicationError( - DefaultErrorMapper.getDefault().parseError(response.code()), - response.code(), + DefaultErrorMapper.getDefault().parseError(response.code), + response.code, "" ) } - val source = response.body()?.source() + val source = response.body?.source() val outputStream = ByteArrayOutputStream() @@ -166,7 +166,7 @@ object S3 { } getObject(objectPathOnNetwork).use { response -> - val source = response.body()?.source() + val source = response.body?.source() val outputStream: OutputStream = if (doNotEncrypt) { FileOutputStream(objectFileOnDisk) diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.kt b/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.kt index 2422480a63..142af786a9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/util/LinkUtil.kt @@ -1,6 +1,6 @@ package org.thoughtcrime.securesms.util -import okhttp3.HttpUrl +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import org.thoughtcrime.securesms.stickers.StickerUrl import java.net.URI import java.net.URISyntaxException @@ -43,7 +43,7 @@ object LinkUtil { return false } - return HttpUrl.parse(linkUrl)?.scheme() == "https" + return linkUrl.toHttpUrlOrNull()?.scheme == "https" } /** diff --git a/dependencies.gradle.kts b/dependencies.gradle.kts index dece736983..95df25e5c3 100644 --- a/dependencies.gradle.kts +++ b/dependencies.gradle.kts @@ -129,8 +129,8 @@ dependencyResolutionManagement { library("greenrobot-eventbus", "org.greenrobot:eventbus:3.0.0") library("jackson-core", "com.fasterxml.jackson.core:jackson-databind:2.9.9.2") library("jackson-module-kotlin", "com.fasterxml.jackson.module:jackson-module-kotlin:2.12.0") - library("square-okhttp3", "com.squareup.okhttp3:okhttp:3.12.13") - library("square-okio", "com.squareup.okio:okio:3.0.0") + library("square-okhttp3", "com.squareup.okhttp3:okhttp:4.12.0") + library("square-okio", "com.squareup.okio:okio:3.6.0") library("square-leakcanary", "com.squareup.leakcanary:leakcanary-android:2.7") library("rxjava3-rxjava", "io.reactivex.rxjava3:rxjava:3.0.13") library("rxjava3-rxandroid", "io.reactivex.rxjava3:rxandroid:3.0.0") @@ -199,7 +199,7 @@ dependencyResolutionManagement { library("bouncycastle-bcpkix-jdk15on", "org.bouncycastle:bcpkix-jdk15on:1.70") library("hamcrest-hamcrest", "org.hamcrest:hamcrest:2.2") library("assertj-core", "org.assertj:assertj-core:3.11.1") - library("square-okhttp-mockserver", "com.squareup.okhttp3:mockwebserver:3.12.13") + library("square-okhttp-mockserver", "com.squareup.okhttp3:mockwebserver:4.12.0") library("mockk", "io.mockk:mockk:1.13.2") library("mockk-android", "io.mockk:mockk-android:1.13.2") diff --git a/donations/lib/src/main/java/org/signal/donations/StripeApi.kt b/donations/lib/src/main/java/org/signal/donations/StripeApi.kt index 6006e461a8..8559433518 100644 --- a/donations/lib/src/main/java/org/signal/donations/StripeApi.kt +++ b/donations/lib/src/main/java/org/signal/donations/StripeApi.kt @@ -146,7 +146,7 @@ class StripeApi( fun getSetupIntent(stripeIntentAccessor: StripeIntentAccessor): StripeSetupIntent { return when (stripeIntentAccessor.objectType) { StripeIntentAccessor.ObjectType.SETUP_INTENT -> get("setup_intents/${stripeIntentAccessor.intentId}?client_secret=${stripeIntentAccessor.intentClientSecret}&expand[0]=latest_attempt").use { - val body = it.body()?.string() + val body = it.body?.string() try { objectMapper.readValue(body!!) } catch (e: InvalidDefinitionException) { @@ -168,7 +168,7 @@ class StripeApi( fun getPaymentIntent(stripeIntentAccessor: StripeIntentAccessor): StripePaymentIntent { return when (stripeIntentAccessor.objectType) { StripeIntentAccessor.ObjectType.PAYMENT_INTENT -> get("payment_intents/${stripeIntentAccessor.intentId}?client_secret=${stripeIntentAccessor.intentClientSecret}").use { - val body = it.body()?.string() + val body = it.body?.string() try { Log.d(TAG, "Reading StripePaymentIntent from JSON") objectMapper.readValue(body!!) @@ -186,7 +186,7 @@ class StripeApi( } private fun getNextAction(response: Response): Pair { - val responseBody = response.body()?.string() + val responseBody = response.body?.string() val bodyJson = responseBody?.let { JSONObject(it) } return if (bodyJson?.has("next_action") == true && !bodyJson.isNull("next_action")) { val nextAction = bodyJson.getJSONObject("next_action") @@ -230,12 +230,8 @@ class StripeApi( ) postForm("tokens", parameters).use { response -> - val body = response.body() - if (body != null) { - return CreditCardPaymentSource(JSONObject(body.string())) - } else { - throw StripeError.FailedToCreatePaymentSourceFromCardData - } + val body = response.body ?: throw StripeError.FailedToCreatePaymentSourceFromCardData + return CreditCardPaymentSource(JSONObject(body.string())) } } @@ -247,13 +243,9 @@ class StripeApi( } return paymentMethodResponse.use { response -> - val body = response.body() - if (body != null) { - val paymentMethodObject = body.string().replace("\n", "").let { JSONObject(it) } - paymentMethodObject.getString("id") - } else { - throw StripeError.FailedToParsePaymentMethodResponseError - } + val body = response.body ?: throw StripeError.FailedToParsePaymentMethodResponseError + val paymentMethodObject = body.string().replace("\n", "").let { JSONObject(it) } + paymentMethodObject.getString("id") } } @@ -320,18 +312,18 @@ class StripeApi( if (response.isSuccessful) { return response } else { - val body = response.body()?.string() + val body = response.body?.string() val errorCode = parseErrorCode(body) val declineCode = parseDeclineCode(body) ?: StripeDeclineCode.getFromCode(errorCode) val failureCode = parseFailureCode(body) ?: StripeFailureCode.getFromCode(errorCode) if (failureCode is StripeFailureCode.Known) { - throw StripeError.PostError.Failed(response.code(), failureCode) + throw StripeError.PostError.Failed(response.code, failureCode) } else if (declineCode is StripeDeclineCode.Known) { - throw StripeError.PostError.Declined(response.code(), declineCode) + throw StripeError.PostError.Declined(response.code, declineCode) } else { - throw StripeError.PostError.Generic(response.code(), errorCode) + throw StripeError.PostError.Generic(response.code, errorCode) } } } diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index cc3c6e5b37..f93fb2de80 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -5741,24 +5741,20 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - + + + + + + - - - + + + - - - - - - - - - + + @@ -5766,11 +5762,6 @@ https://docs.gradle.org/current/userguide/dependency_verification.html - - - - - @@ -5787,6 +5778,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + @@ -5800,6 +5799,14 @@ https://docs.gradle.org/current/userguide/dependency_verification.html + + + + + + + + diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt index 6a76822e59..cb455c9672 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/http/DigestingRequestBody.kt @@ -1,8 +1,8 @@ package org.whispersystems.signalservice.internal.push.http import okhttp3.MediaType +import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody -import okhttp3.internal.http.UnrepeatableRequestBody import okio.BufferedSink import org.signal.libsignal.protocol.incrementalmac.ChunkSizeChoice import org.signal.libsignal.protocol.logging.Log @@ -26,7 +26,7 @@ class DigestingRequestBody( private val progressListener: SignalServiceAttachment.ProgressListener?, private val cancelationSignal: CancelationSignal?, private val contentStart: Long -) : RequestBody(), UnrepeatableRequestBody { +) : RequestBody() { var attachmentDigest: AttachmentDigest? = null init { @@ -35,7 +35,7 @@ class DigestingRequestBody( } override fun contentType(): MediaType? { - return MediaType.parse(contentType) + return contentType.toMediaTypeOrNull() } @Throws(IOException::class) @@ -85,6 +85,10 @@ class DigestingRequestBody( return if (contentLength > 0) contentLength - contentStart else -1 } + override fun isOneShot(): Boolean { + return true + } + private fun logMessage(actual: Long, expected: Long): String { val difference = actual - expected return if (difference > 0) {