Что за ошибка okhttp3 и как ее починить?

Пытаюсь реализовать такую штуку: есть файл, выбранный через filepicker, я его перевожу в string и отправляю в чате на сервер по кускам размером 10к байт. Вот как происходит выбор и нарезка файла:

requestCode == 1 && resultCode == Activity.RESULT_OK -> {
                if (data != null) {
                    val fileUri = data.data!!
                    val partSize = 10000
                    val fileString = readTextFile(fileUri)
                    var name = ""
                    var size: Long? = null

                    fileUri.let { returnUri ->
                        contentResolver.query(returnUri, null, null, null, null)
                    }?.use { cursor ->
                        val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                        val sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE)
                        cursor.moveToFirst()
                        name = cursor.getString(nameIndex)
                        size = cursor.getLong(sizeIndex)
                    }



                    if (fileString!!.length < partSize) {
                        ws.send(ChatRequestMessages.sendFile(fileString,
                                name,
                                selectedContactId.toString(),
                                fileString.length.toLong(),
                                0))
                    } else {
                        val partsCount = if (size!!.rem(partSize).toInt() == 0) {
                            size!!.div(partSize)
                        } else {
                            size!!.div(partSize)
                        }


                        for (currentPart in 0..size!!.div(partSize)) {
                            val slicedString = if ((currentPart + 1) * partSize <= size!!.toInt()) {
                                fileString.substring(currentPart.toInt() * partSize..(currentPart + 1).toInt() * partSize)
                            } else {
                                fileString!!.substring(currentPart.toInt() * partSize until fileString.length)
                            }

                            Timber.i("${fileString.length.toLong()}  ${currentPart * partSize} ${slicedString.length} $slicedString $name")



                            ws.send(ChatRequestMessages.sendFile(slicedString,
                                    name,
                                    selectedContactId.toString(),
                                    fileString.length.toLong(),
                                    (currentPart * partSize).toInt()))
                        }
                    }


                }
            }

и происходит странная ситуация: когда файл размером 14 байт например, все нормально отправляется, когда файл 3кб тоже все нормально, но когда пытаюсь отправить файл размером 12,15 кб то прилетает такая ошибка:

[okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)] 

когда отправляю файл 120кб то получаю такую ошибку:

Read error: ssl=0xdbda0ac0: I/O error during system call, Connection reset by peer null [com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method), com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:741), okio.InputStreamSource.read(JvmOkio.kt:90), okio.AsyncTimeout$source$1.read(AsyncTimeout.kt:129), okio.RealBufferedSource.request(RealBufferedSource.kt:207), okio.RealBufferedSource.require(RealBufferedSource.kt:201), okio.RealBufferedSource.readByte(RealBufferedSource.kt:210), okhttp3.internal.ws.WebSocketReader.readHeader(WebSocketReader.kt:119), okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.kt:102), okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.kt:293), okhttp3.internal.ws.RealWebSocket$connect$1.onResponse(RealWebSocket.kt:195), okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504), java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162), java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636), java.lang.Thread.run(Thread.java:764)] 

не могу понять что не так, и на что влияет размер файла. Может у кого-то была подобная проблема и он ее починил, буду благодарен за любую информацию :)


Ответы (1 шт):

Автор решения: Andrew

Ошибка довольно просто определяется со стороны сервера. Для этого нужно чтобы либо у вас был доступ к бэкенду либо коммуницируйте с разработчиками. В итоге пустив сервер через терминал была получена более удобоваримая ошибка:

open(fp, 'wb').write(form['body'].encode('latin-1'))
UnicodeEncodeError: 'latin-1' codec can't encode character '\ufffd' in position 0: ordinal not in range(256)

Суть ошибки в том что кодек сервера не может обработать передаваемый стринг. Для того чтобы отправить нормальный стринг, который прожуется сервером нормально, нужно имеющийся у вас стринг кодировать по данному стандарту:

String("your_string", Charsets.ISO_8859_1)

На википедии можно найти такое уточнение:

также известный как ISO 8859-1 и Latin-1

соответственно это то что нужно было для сервера.

→ Ссылка