From c663c0ec9deee7281f819f222bb29ad79e99f3b8 Mon Sep 17 00:00:00 2001 From: Hetan Thakkar Date: Tue, 10 May 2022 10:59:40 -0700 Subject: [PATCH] Fixed and added support for dataUri in form data (#33675) Summary: Continuation of https://github.com/facebook/react-native/issues/33548 Fixes https://github.com/facebook/react-native/issues/25790. The issue resulted because the [getFileInputStream() method of RequestBodyUtil failed to return an inputStream of the given dataUri ](https://github.com/facebook/react-native/blob/16397e0d3c0dd3374ddb642599725ca41f092a8a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java#L427) This happened because the openInputStream() method of [context.getContentResolver() expects a content or a file](https://developer.android.com/reference/android/content/ContentResolver#openInputStream(android.net.Uri)) in its parameter but instead received dataUri which resulted in FileNotFoundException. ![issue](https://user-images.githubusercontent.com/38756320/161345967-fd79d3e2-54a8-4a0e-8a6b-189ce9883a78.jpeg) **Solution**: I've now converted the dataUri to bitmap and then attached an inputStream to the compressed bitmap. This way we won't have to store the image temporarily. I think converting the dataUri to Bitmap is necessary as there is no method that lets us convert the dataUri to inputStream directly. And regarding large size images, converting them to bitmap is the only(efficient) step I can think of, as the conversion is handled by in-built java function. This issue has been unresolved for quite some time now, so resolving this PR would be greatly appreciated. ## Changelog [Android] [Added] - Support for dataUri in form data Pull Request resolved: https://github.com/facebook/react-native/pull/33675 Reviewed By: christophpurrer, mdvacca Differential Revision: D36205586 Pulled By: cortinico fbshipit-source-id: bfc83efcec0b2fcb1df42e4bf1d43c966de8f40e --- .../react/modules/network/RequestBodyUtil.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java index a7d5fcf415f6bc..57fa7c58980255 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java @@ -8,10 +8,14 @@ package com.facebook.react.modules.network; import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.net.Uri; +import android.util.Base64; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; import com.facebook.react.common.ReactConstants; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -58,6 +62,16 @@ public static boolean isGzipEncoding(@Nullable final String encodingType) { if (fileContentUri.getScheme().startsWith("http")) { return getDownloadFileInputStream(context, fileContentUri); } + + if (fileContentUriStr.startsWith("data:")) { + byte[] decodedDataUrString = Base64.decode(fileContentUriStr.split(",")[1], Base64.DEFAULT); + Bitmap bitMap = + BitmapFactory.decodeByteArray(decodedDataUrString, 0, decodedDataUrString.length); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + bitMap.compress(Bitmap.CompressFormat.PNG, 0, bytes); + return new ByteArrayInputStream(bytes.toByteArray()); + } + return context.getContentResolver().openInputStream(fileContentUri); } catch (Exception e) { FLog.e(ReactConstants.TAG, "Could not retrieve file for contentUri " + fileContentUriStr, e);