26
26
27
27
class ReactNativeBlobUtilBody extends RequestBody {
28
28
29
- private InputStream requestStream ;
30
29
private long contentLength = 0 ;
31
30
private ReadableArray form ;
32
31
private String mTaskId ;
@@ -71,12 +70,10 @@ ReactNativeBlobUtilBody setBody(String body) {
71
70
try {
72
71
switch (requestType ) {
73
72
case SingleFile :
74
- requestStream = getRequestStream ();
75
- contentLength = requestStream .available ();
73
+ contentLength = getRequestStream ().available ();
76
74
break ;
77
75
case AsIs :
78
76
contentLength = this .rawBody .getBytes ().length ;
79
- requestStream = new ByteArrayInputStream (this .rawBody .getBytes ());
80
77
break ;
81
78
case Others :
82
79
break ;
@@ -98,7 +95,6 @@ ReactNativeBlobUtilBody setBody(ReadableArray body) {
98
95
this .form = body ;
99
96
try {
100
97
bodyCache = createMultipartBodyCache ();
101
- requestStream = new FileInputStream (bodyCache );
102
98
contentLength = bodyCache .length ();
103
99
} catch (Exception ex ) {
104
100
ex .printStackTrace ();
@@ -107,6 +103,34 @@ ReactNativeBlobUtilBody setBody(ReadableArray body) {
107
103
return this ;
108
104
}
109
105
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
+
110
134
@ Override
111
135
public long contentLength () {
112
136
return chunkedEncoding ? -1 : contentLength ;
@@ -120,7 +144,7 @@ public MediaType contentType() {
120
144
@ Override
121
145
public void writeTo (@ NonNull BufferedSink sink ) {
122
146
try {
123
- pipeStreamToSink (requestStream , sink );
147
+ pipeStreamToSink (getInputStreamForRequestBody () , sink );
124
148
} catch (Exception ex ) {
125
149
ReactNativeBlobUtilUtils .emitWarningEvent (ex .getLocalizedMessage ());
126
150
ex .printStackTrace ();
0 commit comments