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

Commit

Permalink
Fix XMLHttpRequest module bugs #44
Browse files Browse the repository at this point in the history
Add Event and ProgressEvent class #44

Add timeout support #44
  • Loading branch information
wkh237 committed Jul 26, 2016
1 parent 4e767a7 commit 2ea0cda
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 150 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public class RNFetchBlobConfig {
public String key;
public String mime;
public Boolean auto;
public long timeout = -1;

RNFetchBlobConfig(ReadableMap options) {
if(options == null)
Expand All @@ -31,6 +32,9 @@ public class RNFetchBlobConfig {
this.key = options.hasKey("key") ? options.getString("key") : null;
this.mime = options.hasKey("contentType") ? options.getString("contentType") : null;
this.auto = options.hasKey("auto") ? options.getBoolean("auto") : false;
if(options.hasKey("timeout")) {
this.timeout = options.getInt("timeout");
}
}

}
75 changes: 42 additions & 33 deletions src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Headers;
Expand Down Expand Up @@ -79,6 +81,7 @@ enum ResponseType {
long downloadManagerId;
RequestType requestType;
ResponseType responseType;
boolean timeout = false;

public RNFetchBlobReq(ReadableMap options, String taskId, String method, String url, ReadableMap headers, String body, ReadableArray arrayBody, final Callback callback) {
this.method = method;
Expand Down Expand Up @@ -257,32 +260,41 @@ else if(this.options.fileCache == true)
clientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(req);
ResponseBody extended;
switch (responseType) {
case KeepInMemory:
extended = new RNFetchBlobDefaultResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body());
break;
case FileStorage:
extended = new RNFetchBlobFileResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body(),
destPath);
break;
default:
extended = new RNFetchBlobDefaultResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body());
break;
}
return originalResponse.newBuilder().body(extended).build();
try {
Response originalResponse = chain.proceed(req);
ResponseBody extended;
switch (responseType) {
case KeepInMemory:
extended = new RNFetchBlobDefaultResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body());
break;
case FileStorage:
extended = new RNFetchBlobFileResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body(),
destPath);
break;
default:
extended = new RNFetchBlobDefaultResp(
RNFetchBlob.RCTContext,
taskId,
originalResponse.body());
break;
}
return originalResponse.newBuilder().body(extended).build();
} catch(SocketTimeoutException ex) {
timeout = true;
}
return chain.proceed(chain.request());
}
});

if(options.timeout != -1) {
clientBuilder.connectTimeout(options.timeout, TimeUnit.SECONDS);
}

OkHttpClient client = clientBuilder.build();
Call call = client.newCall(req);
Expand Down Expand Up @@ -386,34 +398,31 @@ private WritableMap getResponseInfo(Response resp) {
info.putInt("status", resp.code());
info.putString("state", "2");
info.putString("taskId", this.taskId);
info.putBoolean("timeout", timeout);
WritableMap headers = Arguments.createMap();
for(int i =0;i< resp.headers().size();i++) {
headers.putString(resp.headers().name(i), resp.headers().value(i));
}
info.putMap("headers", headers);
Headers h = resp.headers();
if(getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("text/plain"))
{
if(getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("text/plain")) {
info.putString("respType", "text");
}
else if(getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("application/json"))
{
else if(getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("application/json")) {
info.putString("respType", "json");
}
else if(getHeaderIgnoreCases(h, "content-type").length() < 1)
{
else if(getHeaderIgnoreCases(h, "content-type").length() < 1) {
info.putString("respType", "blob");
}
else
{
else {
info.putString("respType", "text");
}
return info;
}

private boolean isBlobResponse(Response resp) {
Headers h = resp.headers();
boolean isText = !getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("text/plain");
boolean isText = !getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("text/");
boolean isJSON = !getHeaderIgnoreCases(h, "content-type").equalsIgnoreCase("application/json");
return !(isJSON || isText);
}
Expand Down
29 changes: 19 additions & 10 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
import fs from './fs'
import getUUID from './utils/uuid'
import base64 from 'base-64'
import polyfill from './polyfill'
const {
RNFetchBlobSession,
readStream,
Expand All @@ -34,7 +35,6 @@ const {
mv,
cp
} = fs
import polyfill from './polyfill'

const Blob = polyfill.Blob
const emitter = DeviceEventEmitter
Expand Down Expand Up @@ -151,7 +151,7 @@ function fetch(...args:any):Promise {
subscriptionUpload.remove()
stateEvent.remove()
if(err)
reject(new Error(err, data))
reject(new Error(err, info))
else {
let rnfbEncode = 'base64'
// response data is saved to storage
Expand All @@ -163,9 +163,9 @@ function fetch(...args:any):Promise {
}
info = info || {}
info.rnfbEncode = rnfbEncode

resolve(new FetchBlobResponse(taskId, info, data))
}

})

})
Expand Down Expand Up @@ -228,14 +228,23 @@ class FetchBlobResponse {
return this.respInfo
}
/**
* Convert result to javascript Blob object.
* @param {string} contentType MIME type of the blob object.
* @param {number} sliceSize Slice size.
* @return {blob} Return Blob object.
* Convert result to javascript RNFetchBlob object.
* @return {Promise<Blob>} Return a promise resolves Blob object.
*/
this.blob = (contentType:string, sliceSize:number) => {
console.warn('FetchBlobResponse.blob() is deprecated and has no funtionality.')
return this
this.blob = ():Promise<Blob> => {
return new Promise((resolve, reject) => {
if(this.type === 'base64') {
try {
let b = new polyfill.Blob(this.data, 'application/octet-stream;BASE64')
b.onCreated(() => {
console.log('####', b)
resolve(b)
})
} catch(err) {
reject(err)
}
}
})
}
/**
* Convert result to text.
Expand Down
25 changes: 17 additions & 8 deletions src/ios/RNFetchBlobNetwork.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#import "RNFetchBlobFS.h"
#import "RNFetchBlobNetwork.h"
#import "RNFetchBlobConst.h"
#import "RNFetchBlobReqBuilder.h"
#import <CommonCrypto/CommonDigest.h>

////////////////////////////////////////
Expand Down Expand Up @@ -113,8 +114,12 @@ - (void) sendRequest:(NSDictionary * _Nullable )options
// the session trust any SSL certification

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
if([options valueForKey:@"timeout"] != nil)
{
defaultConfigObject.timeoutIntervalForRequest = [[options valueForKey:@"timeout"] floatValue];
}
session = [NSURLSession sessionWithConfiguration:defaultConfigObject delegate:self delegateQueue:taskQueue];

if(path != nil || [self.options valueForKey:CONFIG_USE_TEMP]!= nil)
{
respFile = YES;
Expand Down Expand Up @@ -171,10 +176,12 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
if ([response respondsToSelector:@selector(allHeaderFields)])
{
NSDictionary *headers = [httpResponse allHeaderFields];
NSString * respType = [[headers valueForKey:@"Content-Type"] lowercaseString];
NSString * respType = [[RNFetchBlobReqBuilder getHeaderIgnoreCases:@"content-type"
fromHeaders:headers]
lowercaseString];
if([headers valueForKey:@"Content-Type"] != nil)
{
if([respType containsString:@"text/plain"])
if([respType containsString:@"text/"])
{
respType = @"text";
}
Expand All @@ -199,6 +206,7 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
@"state": @"2",
@"headers": headers,
@"respType" : respType,
@"timeout" : @NO,
@"status": [NSString stringWithFormat:@"%d", statusCode ]
};
[self.bridge.eventDispatcher
Expand Down Expand Up @@ -253,22 +261,22 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
}

- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
NSLog([error localizedDescription]);

self.error = error;
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

NSString * respType = [respInfo valueForKey:@"respType"];
if(error != nil) {
NSLog([error localizedDescription]);
}

if(respFile == YES)
{
if(error != nil) {
NSLog([error localizedDescription]);
}
[writeStream close];
callback(@[error == nil ? [NSNull null] : [error localizedDescription],
respInfo == nil ? [NSNull null] : respInfo,
destPath
]);
]);
}
// base64 response
else {
Expand Down Expand Up @@ -347,4 +355,5 @@ - (void) URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthentica
}
}


@end
2 changes: 2 additions & 0 deletions src/ios/RNFetchBlobReqBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
form:(NSString *)body
onComplete:(void(^)(NSURLRequest * req, long bodyLength))onComplete;

+(NSString *) getHeaderIgnoreCases:(NSString *)field fromHeaders:(NSMutableArray *) headers;


@end

Expand Down
11 changes: 11 additions & 0 deletions src/polyfill/Event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2016 wkh237@github. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.

export default class Event {

constructor() {

}

}
29 changes: 28 additions & 1 deletion src/polyfill/EventTarget.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2016 wkh237@github. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.

import Log from '../utils/log.js'

const log = new Log('EventTarget')
Expand All @@ -14,6 +15,11 @@ export default class EventTarget {
this.listeners = {}
}

/**
* Add an event listener to given event type
* @param {string} type Event type string
* @param {(Event) => void} cb Event handler function
*/
addEventListener(type:string, cb : () => void) {
log.info('add event listener', type, cb)
if(!(type in this.listeners)) {
Expand All @@ -22,7 +28,13 @@ export default class EventTarget {
this.listeners[type].push(cb)
}

removeEventListener(type:string, cb:() => any) {
/**
* Remove an event listener
* @param {string} type Type of the event listener
* @param {()=>void} cb Event listener function.
* @return {[type]} [description]
*/
removeEventListener(type:string, cb:() => void) {
log.info('remove event listener', type, cb)
if(!(type in this.listeners))
return
Expand All @@ -35,6 +47,10 @@ export default class EventTarget {
}
}

/**
* Dispatch an event
* @param {Evnet} event Event data payload.
*/
dispatchEvent(event:Event) {
log.info('dispatch event', event)
if(!(event.type in this.listeners))
Expand All @@ -46,4 +62,15 @@ export default class EventTarget {

}

/**
* Remove all registered listeners from this object.
* @nonstandard
* @return {[type]} [description]
*/
clearEventListeners() {
for(let i in this.listeners) {
delete listeners[i]
}
}

}
Loading

0 comments on commit 2ea0cda

Please sign in to comment.