Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add progress callback for uploadFile and downloadFile methods #496

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,12 +403,19 @@ const name = 'picture';
const filePath = ['file:///somepicture.jpg', 'file:///somedocument.doc'];
const name = ['picture', 'document'];

cordova.plugin.http.uploadFile("https://google.com/", {
id: '12',
message: 'test'
}, { Authorization: 'OAuth2: token' }, filePath, name, function(response) {
console.log(response.status);
}, function(response) {
cordova.plugin.http.uploadFile(
"https://google.com/",
{ id: '12', message: 'test' },
{ Authorization: 'OAuth2: token' },
filePath,
name,
function(progressData) {
console.log((progressData.transferred / progressData.total * 100) + ' percent complete')
},
function(response) {
console.log(response.status);
},
function(response) {
console.error(response.error);
});
```
Expand All @@ -422,6 +429,9 @@ cordova.plugin.http.downloadFile(
{ id: '12', message: 'test' },
{ Authorization: 'OAuth2: token' },
'file:///somepicture.jpg',
function(progressData) {
console.log((progressData.transferred / progressData.total * 100) + ' percent complete')
},
// success callback
function(entry, response) {
// prints the filename
Expand Down
39 changes: 38 additions & 1 deletion src/android/com/silkimen/cordovahttp/CordovaHttpDownload.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.silkimen.cordovahttp;

import android.util.Log;

import java.io.File;
import java.net.URI;

Expand All @@ -9,17 +11,27 @@
import com.silkimen.http.HttpRequest;
import com.silkimen.http.TLSConfiguration;

import org.apache.cordova.PluginResult;
import org.apache.cordova.file.FileUtils;
import org.json.JSONException;
import org.json.JSONObject;

class CordovaHttpDownload extends CordovaHttpBase {
private String filePath;

private boolean hasProgressCallback;

public CordovaHttpDownload(String url, JSONObject headers, String filePath, int connectTimeout, int readTimeout,
boolean followRedirects, TLSConfiguration tlsConfiguration, CordovaObservableCallbackContext callbackContext) {
boolean followRedirects, boolean hasProgressCallback, TLSConfiguration tlsConfiguration, CordovaObservableCallbackContext callbackContext) {

super("GET", url, headers, connectTimeout, readTimeout, followRedirects, "text", tlsConfiguration, callbackContext);
this.filePath = filePath;
this.hasProgressCallback = hasProgressCallback;
}

@Override
protected HttpRequest createRequest() throws JSONException {
return new HttpRequest(this.url, this.method, this.hasProgressCallback);
}

@Override
Expand All @@ -37,5 +49,30 @@ protected void processResponse(HttpRequest request, CordovaHttpResponse response
} else {
response.setErrorMessage("There was an error downloading the file");
}

request.progress(null);
}

@Override
protected void sendBody(HttpRequest request) throws Exception {
if (hasProgressCallback) {
int fileLength = request.getConnection().getContentLength();
request.progress(new HttpRequest.UploadProgress() {
public void onUpload(long transferred, long total) {
JSONObject json = new JSONObject();
try {
json.put("isProgress", true);
json.put("transferred", transferred);
json.put("total", fileLength);

PluginResult result = new PluginResult(PluginResult.Status.OK, json);
result.setKeepCallback(true);
callbackContext.getCallbackContext().sendPluginResult(result);
} catch (JSONException e) {
Log.e(TAG, "onUpload progress error", e);
}
}
});
}
}
}
6 changes: 4 additions & 2 deletions src/android/com/silkimen/cordovahttp/CordovaHttpPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,12 @@ private boolean uploadFiles(final JSONArray args, final CallbackContext callback
boolean followRedirect = args.getBoolean(6);
String responseType = args.getString(7);
Integer reqId = args.getInt(8);
boolean hasProgressCallback = args.getBoolean(9);

CordovaObservableCallbackContext observableCallbackContext = new CordovaObservableCallbackContext(callbackContext, reqId);

CordovaHttpUpload upload = new CordovaHttpUpload(url, headers, filePaths, uploadNames, connectTimeout, readTimeout, followRedirect,
responseType, this.tlsConfiguration, this.cordova.getActivity().getApplicationContext(), observableCallbackContext);
hasProgressCallback, responseType, this.tlsConfiguration, this.cordova.getActivity().getApplicationContext(), observableCallbackContext);

startRequest(reqId, observableCallbackContext, upload);

Expand All @@ -183,11 +184,12 @@ private boolean downloadFile(final JSONArray args, final CallbackContext callbac
int readTimeout = args.getInt(4) * 1000;
boolean followRedirect = args.getBoolean(5);
Integer reqId = args.getInt(6);
boolean hasProgressCallback = args.getBoolean(7);

CordovaObservableCallbackContext observableCallbackContext = new CordovaObservableCallbackContext(callbackContext, reqId);

CordovaHttpDownload download = new CordovaHttpDownload(url, headers, filePath, connectTimeout, readTimeout,
followRedirect, this.tlsConfiguration, observableCallbackContext);
followRedirect, hasProgressCallback, this.tlsConfiguration, observableCallbackContext);

startRequest(reqId, observableCallbackContext, download);

Expand Down
31 changes: 30 additions & 1 deletion src/android/com/silkimen/cordovahttp/CordovaHttpUpload.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import android.database.Cursor;
import android.net.Uri;
import android.provider.OpenableColumns;
import android.util.Log;
import android.webkit.MimeTypeMap;

import com.silkimen.http.HttpRequest;
Expand All @@ -17,22 +18,31 @@
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;

import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

class CordovaHttpUpload extends CordovaHttpBase {
private JSONArray filePaths;
private JSONArray uploadNames;
private Context applicationContext;
private boolean hasProgressCallback;

public CordovaHttpUpload(String url, JSONObject headers, JSONArray filePaths, JSONArray uploadNames, int connectTimeout, int readTimeout,
boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration,
boolean followRedirects, boolean hasProgressCallback, String responseType, TLSConfiguration tlsConfiguration,
Context applicationContext, CordovaObservableCallbackContext callbackContext) {

super("POST", url, headers, connectTimeout, readTimeout, followRedirects, responseType, tlsConfiguration, callbackContext);
this.filePaths = filePaths;
this.uploadNames = uploadNames;
this.applicationContext = applicationContext;
this.hasProgressCallback = hasProgressCallback;
}

@Override
protected HttpRequest createRequest() throws JSONException {
return new HttpRequest(this.url, this.method, this.hasProgressCallback);
}

@Override
Expand Down Expand Up @@ -60,6 +70,25 @@ protected void sendBody(HttpRequest request) throws Exception {

request.part(uploadName, fileName, mimeType, inputStream);
}

if (hasProgressCallback) {
request.progress(new HttpRequest.UploadProgress() {
public void onUpload(long transferred, long total) {
JSONObject json = new JSONObject();
try {
json.put("isProgress", true);
json.put("transferred", transferred);
json.put("total", total);

PluginResult result = new PluginResult(PluginResult.Status.OK, json);
result.setKeepCallback(true);
callbackContext.getCallbackContext().sendPluginResult(result);
} catch (JSONException e) {
Log.e(TAG, "onUpload progress error", e);
}
}
});
}
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/android/com/silkimen/http/HttpRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,8 @@ public String run() {

private final String requestMethod;

private boolean hasProgressCallback = false;

private RequestOutputStream output;

private boolean multipart;
Expand Down Expand Up @@ -1378,6 +1380,16 @@ public HttpRequest(final URL url, final String method) throws HttpRequestExcepti
this.requestMethod = method;
}

public HttpRequest(final CharSequence url, final String method, boolean hasProgressCallback) throws HttpRequestException {
try {
this.url = new URL(url.toString());
} catch (MalformedURLException e) {
throw new HttpRequestException(e);
}
this.requestMethod = method;
this.hasProgressCallback = hasProgressCallback;
}

private Proxy createProxy() {
return new Proxy(HTTP, new InetSocketAddress(httpProxyHost, httpProxyPort));
}
Expand Down Expand Up @@ -2553,7 +2565,9 @@ private HttpRequest incrementTotalSize(final long size) {
* @throws IOException
*/
protected HttpRequest closeOutput() throws IOException {
progress(null);
if(!this.hasProgressCallback){
progress(null);
}
if (output == null)
return this;
if (multipart)
Expand Down
24 changes: 22 additions & 2 deletions src/ios/CordovaHttpPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -494,13 +494,22 @@ - (void)uploadFiles:(CDVInvokedUrlCommand*)command {
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
return;
}
} progress:nil success:^(NSURLSessionTask *task, id responseObject) {
} progress:^(NSProgress *progress) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setValue:[NSNumber numberWithBool:YES] forKey:@"isProgress"];
[dictionary setValue:[NSNumber numberWithLongLong:progress.completedUnitCount] forKey:@"transferred"];
[dictionary setValue:[NSNumber numberWithLongLong:progress.totalUnitCount] forKey:@"total"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
} success:^(NSURLSessionTask *task, id responseObject) {
[weakSelf removeRequest:reqId];

NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[self handleSuccess:dictionary withResponse:(NSHTTPURLResponse*)task.response andData:responseObject];

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:NO]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
Expand All @@ -510,6 +519,7 @@ - (void)uploadFiles:(CDVInvokedUrlCommand*)command {
[self handleError:dictionary withResponse:(NSHTTPURLResponse*)task.response error:error];

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:NO]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
Expand Down Expand Up @@ -546,7 +556,15 @@ - (void)downloadFile:(CDVInvokedUrlCommand*)command {
[[SDNetworkActivityIndicator sharedActivityIndicator] startActivity];

@try {
NSURLSessionDataTask *task = [manager GET:url parameters:nil progress: nil success:^(NSURLSessionTask *task, id responseObject) {
NSURLSessionDataTask *task = [manager GET:url parameters:nil progress:^(NSProgress *progress) {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setValue:[NSNumber numberWithBool:YES] forKey:@"isProgress"];
[dictionary setValue:[NSNumber numberWithLongLong:progress.completedUnitCount] forKey:@"transferred"];
[dictionary setValue:[NSNumber numberWithLongLong:progress.totalUnitCount] forKey:@"total"];
CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:YES]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
} success:^(NSURLSessionTask *task, id responseObject) {
[weakSelf removeRequest:reqId];
/*
*
Expand Down Expand Up @@ -605,6 +623,7 @@ - (void)downloadFile:(CDVInvokedUrlCommand*)command {
[dictionary setObject:[filePlugin getDirectoryEntry:filePath isDirectory:NO] forKey:@"file"];

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:NO]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
} failure:^(NSURLSessionTask *task, NSError *error) {
Expand All @@ -614,6 +633,7 @@ - (void)downloadFile:(CDVInvokedUrlCommand*)command {
[dictionary setObject:@"There was an error downloading the file" forKey:@"error"];

CDVPluginResult *pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsDictionary:dictionary];
[pluginResult setKeepCallback:[NSNumber numberWithBool:NO]];
[weakSelf.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
[[SDNetworkActivityIndicator sharedActivityIndicator] stopActivity];
}];
Expand Down
3 changes: 2 additions & 1 deletion www/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,8 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64,
serializer: checkSerializer(options.serializer || globals.serializer),
connectTimeout: checkTimeoutValue(options.connectTimeout || globals.connectTimeout),
readTimeout: checkTimeoutValue(options.readTimeout || globals.readTimeout),
timeout: checkTimeoutValue(options.timeout || globals.timeout)
timeout: checkTimeoutValue(options.timeout || globals.timeout),
onProgress: options.onProgress
};
}
};
26 changes: 20 additions & 6 deletions www/public-interface.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,12 +180,26 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
break;
case 'upload':
var fileOptions = helpers.checkUploadFileOptions(options.filePath, options.name);
exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, fileOptions.filePaths, fileOptions.names, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType, reqId]);
var hasProgressCallback = options.onProgress != null;
exec(function(resp) {
if (resp != null && resp.isProgress) {
options.onProgress(resp);
} else {
onSuccess(resp);
}
}, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, fileOptions.filePaths, fileOptions.names, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType, reqId, hasProgressCallback]);
break;
case 'download':
var filePath = helpers.checkDownloadFilePath(options.filePath);
var onDownloadSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success));
exec(onDownloadSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, headers, filePath, options.connectTimeout, options.readTimeout, options.followRedirect, reqId]);
var hasProgressCallback = options.onProgress != null;
exec(function(resp) {
if (resp != null && resp.isProgress) {
options.onProgress(resp);
} else {
onDownloadSuccess(resp);
}
}, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, headers, filePath, options.connectTimeout, options.readTimeout, options.followRedirect, reqId, hasProgressCallback]);
break;
default:
exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, headers, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType, reqId]);
Expand Down Expand Up @@ -223,12 +237,12 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf
return publicInterface.sendRequest(url, { method: 'options', params: params, headers: headers }, success, failure);
};

function uploadFile(url, params, headers, filePath, name, success, failure) {
return publicInterface.sendRequest(url, { method: 'upload', params: params, headers: headers, filePath: filePath, name: name }, success, failure);
function uploadFile(url, params, headers, filePath, name, onProgress, success, failure) {
return publicInterface.sendRequest(url, { method: 'upload', params: params, headers: headers, filePath: filePath, name: name, onProgress }, success, failure);
}

function downloadFile(url, params, headers, filePath, success, failure) {
return publicInterface.sendRequest(url, { method: 'download', params: params, headers: headers, filePath: filePath }, success, failure);
function downloadFile(url, params, headers, filePath, onProgress, success, failure) {
return publicInterface.sendRequest(url, { method: 'download', params: params, headers: headers, filePath: filePath, onProgress }, success, failure);
}

function abort(requestId , success, failure) {
Expand Down