Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection Reset on Image Upload with OkHttp SSL Exception (AWS Specific, Network Dependent) #670

Open
2 tasks
kabirnayeem99 opened this issue Dec 15, 2024 · 0 comments

Comments

@kabirnayeem99
Copy link

kabirnayeem99 commented Dec 15, 2024

Describe the bug
When attempting to upload an image using OkHttp via Android Upload Service to Amazon AWS S3, the upload fails with a java.net.SocketException: Connection reset. This issue occurs specifically during the SSL handshake and seems to be related to network conditions.

The issue is reproducible only when using the Zain network operator (in the Middle East). Switching to STC and turning off the VPN resolves the issue, and the upload works as expected.

To Reproduce
Steps to reproduce the behavior:

  1. Set up an image upload request using OkHttp in the Android Upload Service to an Amazon AWS S3 endpoint (pre-signed URL).
  2. Use a device with a SIM card from Zain as the network operator, and VPN turned on.
  3. Attempt to upload the image file.
  4. Observe the error during the upload process.
  5. Repeat the same process with STC as the network operator & VPN turned off, and observe that the issue is resolved.

Expected behavior
The image upload should successfully complete over an HTTPS connection regardless of the network operator.

Screenshots
N/A

OS and Lib versions (please complete the following information):

  • Android Upload Service version: 4.9.2
  • Android version and API version: Android 14
  • HTTP stack: OkHttpStack

Request code:

  suspend fun uploadPhoto(
        uploadId: String,
        preSignedUrl: String,
        mimeType: String,
        filePath: String,
        postName: String,
    ) {
        val random = Random(System.currentTimeMillis())
        delay(random.nextLong(260) + 20)
        val currentTasks = UploadService.taskList
        if (currentTasks.contains(uploadId)) {
            Timber.w("uploadPhoto: Upload ID $uploadId is already being uploaded to $preSignedUrl.")
            return
        }
        if (preSignedUrl.isBlank()) return
        if (filePath.isBlank()) return

        val userAgent = Util.getUserAgent()
        val notificationConfig = generateUploadNotificationConfig(
            postName = postName, uploadId = uploadId
        )

        Timber.i("uploadPhoto: Uploading with these info: \n\tupload id: $uploadId\n\tpre-signed url: $preSignedUrl\n\tmime-type: $mimeType\n\tfile path: $filePath\n")

        val request = BinaryUploadRequest(context, preSignedUrl)
        request.apply {
            setUploadID(uploadId)
            setMethod("PUT")
            addHeader("User-Agent", userAgent)
            addHeader("Content-Type", mimeType)
            setFileToUpload(filePath)
            if (notificationConfig != null) setNotificationConfig { _, _ -> notificationConfig }
            Timber.i("uploadPhoto: Starting upload for id $uploadId on url $preSignedUrl with name $postName")
            startUpload()
        }
    }

Where have you added the request code?

  • Activity
  • Service
  • [-] Other class: in data layer, in remote data source class, that is a singleton.

Debug Log:

java.net.SocketException: Connection reset
    at java.net.SocketInputStream.read(SocketInputStream.java:191)
    at java.net.SocketInputStream.read(SocketInputStream.java:143)
    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.readFromSocket(ConscryptEngineSocket.java:985)
    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:949)
    at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:238)
    at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:220)
    at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:379)
    at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:337)
    at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:209)
    at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:226)
    at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:106)
    at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:74)
    at okhttp3.internal.connection.RealCall.initExchange$okhttp(RealCall.kt:255)
    at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:32)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at com.syarah.photographers.modules.app.MainApplication.onOnIntercept(MainApplication.java:365)
    at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
    at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
    at okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
    at com.google.firebase.perf.network.FirebasePerfOkHttpClient.execute(FirebasePerfOkHttpClient.java:44)
    at net.gotev.uploadservice.okhttp.OkHttpStackRequest.getResponse(OkHttpStackRequest.kt:94)
    at net.gotev.uploadservice.HttpUploadTask.upload(HttpUploadTask.kt:50)
    at net.gotev.uploadservice.UploadTask.run(UploadTask.kt:144)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant