0

I'm trying to upload an image (in streams) on the s3 presignedURL. However, it's giving me 403. The same file when uploaded via POSTMAN works, but not when done via retrofit. What am I missing?

The following is my code:-

val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)//bitmap is the bitmap of the image
val byteArray = stream.toByteArray()
val encodedImage = Base64.encodeToString(byteArray, Base64.DEFAULT)
val requestBody : RequestBody = encodedImage.toRequestBody()// for base64 format              


val url = 'https://s3.presigned_url.com'
val baseUrl = url.split(".com").toTypedArray()[0] + ".com"
var queryUrl: String? = url.split(".com").toTypedArray()[1]

val client = OkHttpClient.Builder().build()

val retrofit_image_upload: Retrofit = Retrofit.Builder()
    .baseUrl(baseUrl)
    .addConverterFactory(GsonConverterFactory.create())
    .client(client)
    .build()

var request1 = retrofit_image_upload.create(Api::class.java)
try {
    request1.upload(
        url,
        fileSize,//size of the image
        requestBody,
    ).enqueue(
        object : retrofit2.Callback<Void> {
            override fun onResponse(call: Call<Void>, response: Response<Void>) {
                println(response.code().toString())
            }
            override fun onFailure(call: Call<Void>, t: Throwable) {
                println(t.toString())
            }
        }
    )
} catch (e: IOException) {
    e.printStackTrace()
}

And here is the upload method:-

@PUT
fun upload(
    @Url url: String,
    @Header("content-length") contentlength: Int,
    @Body image: RequestBody,
): Call<Void>

Also converted the request body into streams but the result is the same.

I referred below articles but still cannot resolve it.

Android HttpURLConnection PUT to Amazon AWS S3 403 error

PUT upload file to AWS S3 presigned url Retrofit2 Android

https://gutier.io/post/android-upload-file-to-aws-s3-bucket-with-retrofit2/

1 Answers1

0

Use http url connection

val connection: HttpURLConnection = URL(presignedUrl).openConnection() as HttpURLConnection
connection.doOutput = true`
connection.setRequestProperty("Content-Type", "image/png")
connection.requestMethod = "PUT"
val out =  DataOutputStream(connection.outputStream)
val fileBytes = file.readBytes()
out.write(fileBytes)
out.close()
if (connection.responseCode == 200){
   TODO
}`