2626
2727class ReactNativeBlobUtilBody extends RequestBody {
2828
29- private InputStream requestStream ;
3029 private long contentLength = 0 ;
3130 private ReadableArray form ;
3231 private String mTaskId ;
@@ -71,12 +70,10 @@ ReactNativeBlobUtilBody setBody(String body) {
7170 try {
7271 switch (requestType ) {
7372 case SingleFile :
74- requestStream = getRequestStream ();
75- contentLength = requestStream .available ();
73+ contentLength = getRequestStream ().available ();
7674 break ;
7775 case AsIs :
7876 contentLength = this .rawBody .getBytes ().length ;
79- requestStream = new ByteArrayInputStream (this .rawBody .getBytes ());
8077 break ;
8178 case Others :
8279 break ;
@@ -98,7 +95,6 @@ ReactNativeBlobUtilBody setBody(ReadableArray body) {
9895 this .form = body ;
9996 try {
10097 bodyCache = createMultipartBodyCache ();
101- requestStream = new FileInputStream (bodyCache );
10298 contentLength = bodyCache .length ();
10399 } catch (Exception ex ) {
104100 ex .printStackTrace ();
@@ -107,6 +103,34 @@ ReactNativeBlobUtilBody setBody(ReadableArray body) {
107103 return this ;
108104 }
109105
106+ // This organizes the input stream initialization logic into a method. This allows:
107+ // 1) Initialization to be deferred until it's needed (when we are ready to pipe it into the BufferedSink)
108+ // 2) The stream to be initialized and used as many times as necessary. When okhttp runs into
109+ // a connection error, it will retry the request which will require a new stream to write into
110+ // the sink once again.
111+ InputStream getInputStreamForRequestBody () {
112+ try {
113+ if (this .form != null ) {
114+ return new FileInputStream (bodyCache );
115+ } else {
116+ switch (requestType ) {
117+ case SingleFile :
118+ return getRequestStream ();
119+ case AsIs :
120+ return new ByteArrayInputStream (this .rawBody .getBytes ());
121+ case Others :
122+ ReactNativeBlobUtilUtils .emitWarningEvent ("ReactNativeBlobUtil could not create input stream for request type others" );
123+ break ;
124+ }
125+ }
126+ } catch (Exception ex ){
127+ ex .printStackTrace ();
128+ ReactNativeBlobUtilUtils .emitWarningEvent ("ReactNativeBlobUtil failed to create input stream for request:" + ex .getLocalizedMessage ());
129+ }
130+
131+ return null ;
132+ }
133+
110134 @ Override
111135 public long contentLength () {
112136 return chunkedEncoding ? -1 : contentLength ;
@@ -120,7 +144,7 @@ public MediaType contentType() {
120144 @ Override
121145 public void writeTo (@ NonNull BufferedSink sink ) {
122146 try {
123- pipeStreamToSink (requestStream , sink );
147+ pipeStreamToSink (getInputStreamForRequestBody () , sink );
124148 } catch (Exception ex ) {
125149 ReactNativeBlobUtilUtils .emitWarningEvent (ex .getLocalizedMessage ());
126150 ex .printStackTrace ();
0 commit comments