gpt4 book ai didi

android - 使用 OkHttp 上传到预签名的 S3 URL 失败

转载 作者:行者123 更新时间:2023-11-29 19:02:26 33 4
gpt4 key购买 nike

当我尝试使用 OkHttp 3.9.1 将文件上传到 Amazon S3 的预签名 URL 时,出现 SSL 异常:SSLException: Write error: ssl=0xa0b73280: I/O error during system call, Connection由同行重置

这与 another SO question 中的问题相同但就我而言,它总是失败。我只上传超过 1MiB 的文件,我没有尝试过小文件。

正如我在那个问题的回答中提到的,切换到 Java 的 HttpURLConnection 解决了问题并且上传工作完美。

这是我的 RequestBody 实现(在 Kotlin 中),用于从 Android 的 Uri 上传文件,我确实使用了 OkHttp 的 .put() 方法:

class UriRequestBody(private val file: Uri, private val contentResolver: ContentResolver, private val mediaType: MediaType = MediaType.parse("application/octet-stream")!!): RequestBody() {
override fun contentLength(): Long = -1L

override fun contentType(): MediaType? = mediaType

override fun writeTo(sink: BufferedSink) {
Okio.source((contentResolver.openInputStream(file))).use {
sink.writeAll(it)
}
}
}

这是我的HttpURLConnection 实现:

private fun uploadFileRaw(file: Uri, uploadUrl: String, contentResolver: ContentResolver) : Int {
val url = URL(uploadUrl)
val connection = url.openConnection() as HttpURLConnection
connection.doOutput = true
connection.requestMethod = "PUT"
val out = connection.outputStream

contentResolver.openInputStream(file).use {
it.copyTo(out)
}

out.close()
return connection.responseCode
}

OkHttp 做了什么不同的事情来导致这个 SSL 异常?

编辑:

这是上传文件的 OkHttp 代码(使用默认的 application/octet-stream mime 类型):

val s3UploadClient = OkHttpClient().newBuilder()
.connectTimeout(30_000L, TimeUnit.MILLISECONDS)
.readTimeout(30_000L, TimeUnit.MILLISECONDS)
.writeTimeout(60_000L, TimeUnit.MILLISECONDS)
.retryOnConnectionFailure(true)
.build()

val body: RequestBody = UriRequestBody(file, contentResolver)
val request = Request.Builder()
.url(uploadUrl)
.put(body)
.build()

s3UploadClient.newCall(request).execute()

这是生成预签名上传 URL 的 JavaScript 服务器代码:

const s3 = new aws.S3({
region: 'us-west-2',
signatureVersion: 'v4'
});
const signedUrlExpireSeconds = 60 * 5;

const signedUrl = s3.getSignedUrl('putObject', {
Bucket: config.bucket.name,
Key: `${fileName}`,
Expires: signedUrlExpireSeconds
});

最佳答案

这似乎适用于改造库:

fun uploadImage(imagePath: String, directUrl: String): Boolean {
Log.d(TAG, "Image: ${imagePath}, Url: $directUrl")
val request = Request.Builder()
.url(directUrl)
.put(RequestBody.create(null, File(imagePath)))
.build()
val response = WebClient.getOkHttpClient().newCall(request).execute()
return response.isSuccessful
}

关于android - 使用 OkHttp 上传到预签名的 S3 URL 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48504394/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com