Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit 467788b

Browse files
committed
Add support of switch chunked transfer encoding #117
1 parent 4f3da5e commit 467788b

File tree

3 files changed

+83
-81
lines changed

3 files changed

+83
-81
lines changed

Diff for: src/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java

+42-31
Original file line numberDiff line numberDiff line change
@@ -34,42 +34,35 @@ public class RNFetchBlobBody extends RequestBody{
3434
RNFetchBlobReq.RequestType requestType;
3535
MediaType mime;
3636
File bodyCache;
37+
Boolean chunkedEncoding = false;
3738

3839

39-
/**
40-
* Single file or raw content request constructor
41-
* @param taskId
42-
* @param type
43-
* @param form
44-
* @param contentType
45-
*/
46-
public RNFetchBlobBody(String taskId, RNFetchBlobReq.RequestType type, ReadableArray form, MediaType contentType) {
40+
public RNFetchBlobBody(String taskId) {
4741
this.mTaskId = taskId;
48-
this.form = form;
49-
requestType = type;
50-
mime = contentType;
51-
try {
52-
bodyCache = createMultipartBodyCache();
53-
requestStream = new FileInputStream(bodyCache);
54-
contentLength = bodyCache.length();
55-
} catch(Exception ex) {
56-
ex.printStackTrace();
57-
RNFetchBlobUtils.emitWarningEvent("RNFetchBlob failed to create request multipart body :" + ex.getLocalizedMessage());
58-
}
42+
}
43+
44+
RNFetchBlobBody chunkedEncoding(boolean val) {
45+
this.chunkedEncoding = val;
46+
return this;
47+
}
48+
49+
RNFetchBlobBody setMIME(MediaType mime) {
50+
this.mime = mime;
51+
return this;
52+
}
53+
54+
RNFetchBlobBody setRequestType( RNFetchBlobReq.RequestType type) {
55+
this.requestType = type;
56+
return this;
5957
}
6058

6159
/**
62-
* Multipart request constructor
63-
* @param taskId
64-
* @param type
65-
* @param rawBody
66-
* @param contentType
60+
* Set request body
61+
* @param body A string represents the request body
62+
* @return object itself
6763
*/
68-
public RNFetchBlobBody(String taskId, RNFetchBlobReq.RequestType type, String rawBody, MediaType contentType) {
69-
this.mTaskId = taskId;
70-
requestType = type;
71-
this.rawBody = rawBody;
72-
mime = contentType;
64+
RNFetchBlobBody setBody(String body) {
65+
this.rawBody = body;
7366
if(rawBody == null) {
7467
this.rawBody = "";
7568
requestType = RNFetchBlobReq.RequestType.AsIs;
@@ -90,19 +83,37 @@ public RNFetchBlobBody(String taskId, RNFetchBlobReq.RequestType type, String ra
9083
ex.printStackTrace();
9184
RNFetchBlobUtils.emitWarningEvent("RNFetchBlob failed to create single content request body :" + ex.getLocalizedMessage() + "\r\n");
9285
}
86+
return this;
87+
}
9388

89+
/**
90+
* Set request body (Array)
91+
* @param body A Readable array contains form data
92+
* @return object itself
93+
*/
94+
RNFetchBlobBody setBody(ReadableArray body) {
95+
this.form = body;
96+
try {
97+
bodyCache = createMultipartBodyCache();
98+
requestStream = new FileInputStream(bodyCache);
99+
contentLength = bodyCache.length();
100+
} catch(Exception ex) {
101+
ex.printStackTrace();
102+
RNFetchBlobUtils.emitWarningEvent("RNFetchBlob failed to create request multipart body :" + ex.getLocalizedMessage());
103+
}
104+
return this;
94105
}
95106

96107
@Override
97108
public long contentLength() {
98-
return contentLength;
109+
return chunkedEncoding ? -1 : contentLength;
99110
}
100111

101112
@Override
102113
public MediaType contentType() {
103114
return mime;
104115
}
105-
116+
106117
@Override
107118
public void writeTo(BufferedSink sink) {
108119
try {

Diff for: src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java

+32-49
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.facebook.react.bridge.ReadableArray;
1818
import com.facebook.react.bridge.ReadableMap;
1919
import com.facebook.react.bridge.ReadableMapKeySetIterator;
20-
import com.facebook.react.bridge.WritableArray;
2120
import com.facebook.react.bridge.WritableMap;
2221
import com.facebook.react.modules.core.DeviceEventManagerModule;
2322

@@ -33,7 +32,6 @@
3332
import java.nio.charset.CharacterCodingException;
3433
import java.nio.charset.Charset;
3534
import java.nio.charset.CharsetEncoder;
36-
import java.util.ArrayList;
3735
import java.util.HashMap;
3836
import java.util.concurrent.TimeUnit;
3937

@@ -74,7 +72,6 @@ enum ResponseType {
7472

7573
ReactApplicationContext ctx;
7674
RNFetchBlobConfig options;
77-
ArrayList<String> redirects = new ArrayList<>();
7875
String taskId;
7976
String method;
8077
String url;
@@ -107,7 +104,7 @@ public RNFetchBlobReq(ReadableMap options, String taskId, String method, String
107104
responseType = ResponseType.KeepInMemory;
108105

109106

110-
if (body != null)
107+
if (body != null)
111108
requestType = RequestType.SingleFile;
112109
else if (arrayBody != null)
113110
requestType = RequestType.Form;
@@ -159,21 +156,21 @@ public void run() {
159156

160157
// find cached result if `key` property exists
161158
String cacheKey = this.taskId;
162-
String ext = this.options.appendExt.isEmpty() ? "." + this.options.appendExt : "";
159+
String ext = this.options.appendExt.isEmpty() ? "." + this.options.appendExt : "";
163160

164-
if (this.options.key != null) {
165-
cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
166-
if (cacheKey == null) {
167-
cacheKey = this.taskId;
168-
}
161+
if (this.options.key != null) {
162+
cacheKey = RNFetchBlobUtils.getMD5(this.options.key);
163+
if (cacheKey == null) {
164+
cacheKey = this.taskId;
165+
}
169166

170-
File file = new File(RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey) + ext);
167+
File file = new File(RNFetchBlobFS.getTmpPath(RNFetchBlob.RCTContext, cacheKey) + ext);
171168

172-
if (file.exists()) {
173-
callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, file.getAbsolutePath());
174-
return;
175-
}
176-
}
169+
if (file.exists()) {
170+
callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, file.getAbsolutePath());
171+
return;
172+
}
173+
}
177174

178175
if(this.options.path != null)
179176
this.destPath = this.options.path;
@@ -239,35 +236,33 @@ else if(cType.isEmpty()) {
239236
requestType = RequestType.WithoutBody;
240237
}
241238

239+
boolean isChunkedRequest = getHeaderIgnoreCases(mheaders, "Transfer-Encoding").equalsIgnoreCase("chunked");
242240

243241
// set request body
244242
switch (requestType) {
245243
case SingleFile:
246-
requestBody = new RNFetchBlobBody(
247-
taskId,
248-
requestType,
249-
rawRequestBody,
250-
MediaType.parse(getHeaderIgnoreCases(mheaders, "content-type"))
251-
);
244+
requestBody = new RNFetchBlobBody(taskId)
245+
.chunkedEncoding(isChunkedRequest)
246+
.setRequestType(requestType)
247+
.setBody(rawRequestBody)
248+
.setMIME(MediaType.parse(getHeaderIgnoreCases(mheaders, "content-type")));
252249
builder.method(method, requestBody);
253250
break;
254251
case AsIs:
255-
requestBody = new RNFetchBlobBody(
256-
taskId,
257-
requestType,
258-
rawRequestBody,
259-
MediaType.parse(getHeaderIgnoreCases(mheaders, "content-type"))
260-
);
252+
requestBody = new RNFetchBlobBody(taskId)
253+
.chunkedEncoding(isChunkedRequest)
254+
.setRequestType(requestType)
255+
.setBody(rawRequestBody)
256+
.setMIME(MediaType.parse(getHeaderIgnoreCases(mheaders, "content-type")));
261257
builder.method(method, requestBody);
262258
break;
263259
case Form:
264260
String boundary = "RNFetchBlob-" + taskId;
265-
requestBody = new RNFetchBlobBody(
266-
taskId,
267-
requestType,
268-
rawRequestBodyArray,
269-
MediaType.parse("multipart/form-data; boundary="+ boundary)
270-
);
261+
requestBody = new RNFetchBlobBody(taskId)
262+
.chunkedEncoding(isChunkedRequest)
263+
.setRequestType(requestType)
264+
.setBody(rawRequestBodyArray)
265+
.setMIME(MediaType.parse("multipart/form-data; boundary="+ boundary));
271266
builder.method(method, requestBody);
272267
break;
273268

@@ -283,15 +278,6 @@ else if(cType.isEmpty()) {
283278

284279
final Request req = builder.build();
285280

286-
// intercept network redirections
287-
clientBuilder.addNetworkInterceptor(new Interceptor() {
288-
@Override
289-
public Response intercept(Chain chain) throws IOException {
290-
redirects.add(chain.request().url().toString());
291-
return chain.proceed(chain.request());
292-
}
293-
});
294-
295281
// Add request interceptor for upload progress event
296282
clientBuilder.addInterceptor(new Interceptor() {
297283
@Override
@@ -468,7 +454,9 @@ private void done(Response resp) {
468454
// It uses customized response body which is able to report download progress
469455
// and write response data to destination path.
470456
resp.body().bytes();
471-
} catch (Exception ignored) { }
457+
} catch (Exception ignored) {
458+
ignored.printStackTrace();
459+
}
472460
callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
473461
break;
474462
default:
@@ -521,11 +509,6 @@ private WritableMap getResponseInfo(Response resp, boolean isBlobResp) {
521509
headers.putString(resp.headers().name(i), resp.headers().value(i));
522510
}
523511
info.putMap("headers", headers);
524-
WritableArray redirectList = Arguments.createArray();
525-
for(String r : redirects) {
526-
redirectList.pushString(r);
527-
}
528-
info.putArray("redirects", redirectList);
529512
Headers h = resp.headers();
530513
if(isBlobResp) {
531514
info.putString("respType", "blob");

Diff for: src/ios/RNFetchBlobReqBuilder.m

+9-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ +(void) buildOctetRequest:(NSDictionary *)options
9090
// generate octet-stream body
9191
if(body != nil) {
9292
__block NSString * cType = [[self class] getHeaderIgnoreCases:@"content-type" fromHeaders:mheaders];
93+
__block NSString * transferEncoding = [[self class] getHeaderIgnoreCases:@"transfer-encoding" fromHeaders:mheaders];
9394
// when headers does not contain a key named "content-type" (case ignored), use default content type
9495
if(cType == nil)
9596
{
@@ -111,7 +112,14 @@ +(void) buildOctetRequest:(NSDictionary *)options
111112
return;
112113
}
113114
size = [[[NSFileManager defaultManager] attributesOfItemAtPath:orgPath error:nil] fileSize];
114-
[request setHTTPBodyStream: [NSInputStream inputStreamWithFileAtPath:orgPath ]];
115+
if(transferEncoding != nil && [[transferEncoding lowercaseString] isEqualToString:@"chunked"])
116+
{
117+
[request setHTTPBodyStream: [NSInputStream inputStreamWithFileAtPath:orgPath ]];
118+
}
119+
else
120+
{
121+
[request setHTTPBody:[NSData dataWithContentsOfFile:orgPath ]];
122+
}
115123
}
116124
// otherwise convert it as BASE64 data string
117125
else {

0 commit comments

Comments
 (0)