From 6797d2c3e055d1b022d1f67f2a8f4676838e73d7 Mon Sep 17 00:00:00 2001 From: Pascal Brogle Date: Thu, 5 Mar 2020 15:46:25 +0100 Subject: [PATCH 1/4] apply timeout correctly on android Also set connectTimeout --- src/android/com/silkimen/cordovahttp/CordovaHttpBase.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java b/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java index 277f8e7..5d503e6 100644 --- a/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java +++ b/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java @@ -122,6 +122,7 @@ abstract class CordovaHttpBase implements Runnable { protected void prepareRequest(HttpRequest request) throws JSONException, IOException { request.followRedirects(this.followRedirects); request.readTimeout(this.timeout); + request.connectTimeout(this.timeout); request.acceptCharset("UTF-8"); request.uncompress(true); HttpRequest.setConnectionFactory(new OkConnectionFactory()); From 4687bad20d240b1f9e364d23a08ad1601ebe3955 Mon Sep 17 00:00:00 2001 From: YouYue123 Date: Thu, 18 Mar 2021 22:18:00 +0800 Subject: [PATCH 2/4] 1. Add connectTimeout getter, setter 2. Add readTimeout getter, setter 3. Modify android and ios part to take from connect and readtimeout 4. update docs --- README.md | 16 +++++++-- .../silkimen/cordovahttp/CordovaHttpBase.java | 19 ++++++----- .../cordovahttp/CordovaHttpDownload.java | 6 ++-- .../cordovahttp/CordovaHttpOperation.java | 8 ++--- .../cordovahttp/CordovaHttpUpload.java | 4 +-- src/ios/CordovaHttpPlugin.m | 34 +++++++++++-------- test/js-specs.js | 22 ++++++++++++ www/global-configs.js | 2 ++ www/helpers.js | 4 ++- www/public-interface.js | 33 +++++++++++++++--- 10 files changed, 108 insertions(+), 40 deletions(-) diff --git a/README.md b/README.md index 95980c0..b3a820b 100644 --- a/README.md +++ b/README.md @@ -115,11 +115,24 @@ This defaults to `urlencoded`. You can also override the default content type he ### setRequestTimeout Set how long to wait for a request to respond, in seconds. - +For Android, this will set both [connectTimeout](https://developer.android.com/reference/java/net/URLConnection#getConnectTimeout()) and [readTimeout](https://developer.android.com/reference/java/net/URLConnection#setReadTimeout(int)) +For iOS, this will set [timeout interval](https://developer.apple.com/documentation/foundation/nsmutableurlrequest/1414063-timeoutinterval) ```js cordova.plugin.http.setRequestTimeout(5.0); ``` +### setConnectTimeout (Android Only) +Set connect timeout for Android +```js +cordova.plugin.http.setRequestTimeout(5.0); +``` + +### setReadTimeout (Android Only) +Set read timeout for Android +```js +cordova.plugin.http.setReadTimeout(5.0); +``` + ### setFollowRedirect Configure if it should follow redirects automatically. This defaults to true. @@ -237,7 +250,6 @@ cordova.plugin.http.sendRequest('https://google.com/', options, function(respons }, function(response) { // prints 403 console.log(response.status); - //prints Permission denied console.log(response.error); }); diff --git a/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java b/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java index 5d503e6..8f8b6a9 100644 --- a/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java +++ b/src/android/com/silkimen/cordovahttp/CordovaHttpBase.java @@ -37,13 +37,14 @@ abstract class CordovaHttpBase implements Runnable { protected String responseType; protected Object data; protected JSONObject headers; - protected int timeout; + protected int connectTimeout; + protected int readTimeout; protected boolean followRedirects; protected TLSConfiguration tlsConfiguration; protected CallbackContext callbackContext; - public CordovaHttpBase(String method, String url, String serializer, Object data, JSONObject headers, int timeout, - boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, + public CordovaHttpBase(String method, String url, String serializer, Object data, JSONObject headers, int connectTimeout, + int readTimeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { this.method = method; @@ -51,20 +52,22 @@ abstract class CordovaHttpBase implements Runnable { this.serializer = serializer; this.data = data; this.headers = headers; - this.timeout = timeout; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; this.followRedirects = followRedirects; this.responseType = responseType; this.tlsConfiguration = tlsConfiguration; this.callbackContext = callbackContext; } - public CordovaHttpBase(String method, String url, JSONObject headers, int timeout, boolean followRedirects, + public CordovaHttpBase(String method, String url, JSONObject headers, int connectTimeout, int readTimeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { this.method = method; this.url = url; this.headers = headers; - this.timeout = timeout; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; this.followRedirects = followRedirects; this.responseType = responseType; this.tlsConfiguration = tlsConfiguration; @@ -121,8 +124,8 @@ abstract class CordovaHttpBase implements Runnable { protected void prepareRequest(HttpRequest request) throws JSONException, IOException { request.followRedirects(this.followRedirects); - request.readTimeout(this.timeout); - request.connectTimeout(this.timeout); + request.connectTimeout(this.connectTimeout); + request.readTimeout(this.readTimeout); request.acceptCharset("UTF-8"); request.uncompress(true); HttpRequest.setConnectionFactory(new OkConnectionFactory()); diff --git a/src/android/com/silkimen/cordovahttp/CordovaHttpDownload.java b/src/android/com/silkimen/cordovahttp/CordovaHttpDownload.java index d89db82..98bca77 100644 --- a/src/android/com/silkimen/cordovahttp/CordovaHttpDownload.java +++ b/src/android/com/silkimen/cordovahttp/CordovaHttpDownload.java @@ -16,10 +16,10 @@ import org.json.JSONObject; class CordovaHttpDownload extends CordovaHttpBase { private String filePath; - public CordovaHttpDownload(String url, JSONObject headers, String filePath, int timeout, boolean followRedirects, - TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { + public CordovaHttpDownload(String url, JSONObject headers, String filePath, int connectTimeout, int readTimeout, + boolean followRedirects, TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { - super("GET", url, headers, timeout, followRedirects, "text", tlsConfiguration, callbackContext); + super("GET", url, headers, connectTimeout, readTimeout, followRedirects, "text", tlsConfiguration, callbackContext); this.filePath = filePath; } diff --git a/src/android/com/silkimen/cordovahttp/CordovaHttpOperation.java b/src/android/com/silkimen/cordovahttp/CordovaHttpOperation.java index 5f17e5d..9526b50 100644 --- a/src/android/com/silkimen/cordovahttp/CordovaHttpOperation.java +++ b/src/android/com/silkimen/cordovahttp/CordovaHttpOperation.java @@ -10,16 +10,16 @@ import org.json.JSONObject; class CordovaHttpOperation extends CordovaHttpBase { public CordovaHttpOperation(String method, String url, String serializer, Object data, JSONObject headers, - int timeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, + int connectTimeout, int readTimeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { - super(method, url, serializer, data, headers, timeout, followRedirects, responseType, tlsConfiguration, + super(method, url, serializer, data, headers, connectTimeout, readTimeout, followRedirects, responseType, tlsConfiguration, callbackContext); } - public CordovaHttpOperation(String method, String url, JSONObject headers, int timeout, boolean followRedirects, + public CordovaHttpOperation(String method, String url, JSONObject headers, int connectTimeout, int readTimeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, CallbackContext callbackContext) { - super(method, url, headers, timeout, followRedirects, responseType, tlsConfiguration, callbackContext); + super(method, url, headers, connectTimeout, readTimeout, followRedirects, responseType, tlsConfiguration, callbackContext); } } diff --git a/src/android/com/silkimen/cordovahttp/CordovaHttpUpload.java b/src/android/com/silkimen/cordovahttp/CordovaHttpUpload.java index dcbcd06..d98b961 100644 --- a/src/android/com/silkimen/cordovahttp/CordovaHttpUpload.java +++ b/src/android/com/silkimen/cordovahttp/CordovaHttpUpload.java @@ -26,11 +26,11 @@ class CordovaHttpUpload extends CordovaHttpBase { private JSONArray uploadNames; private Context applicationContext; - public CordovaHttpUpload(String url, JSONObject headers, JSONArray filePaths, JSONArray uploadNames, int timeout, + public CordovaHttpUpload(String url, JSONObject headers, JSONArray filePaths, JSONArray uploadNames, int connectTimeout, int readTimeout, boolean followRedirects, String responseType, TLSConfiguration tlsConfiguration, Context applicationContext, CallbackContext callbackContext) { - super("POST", url, headers, timeout, followRedirects, responseType, tlsConfiguration, callbackContext); + super("POST", url, headers, connectTimeout, readTimeout, followRedirects, responseType, tlsConfiguration, callbackContext); this.filePaths = filePaths; this.uploadNames = uploadNames; this.applicationContext = applicationContext; diff --git a/src/ios/CordovaHttpPlugin.m b/src/ios/CordovaHttpPlugin.m index 2f8c750..3fd2c20 100644 --- a/src/ios/CordovaHttpPlugin.m +++ b/src/ios/CordovaHttpPlugin.m @@ -151,13 +151,14 @@ NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *headers = [command.arguments objectAtIndex:1]; - NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:2] doubleValue]; - bool followRedirect = [[command.arguments objectAtIndex:3] boolValue]; - NSString *responseType = [command.arguments objectAtIndex:4]; + NSTimeInterval connectTimeout = [[command.arguments objectAtIndex:2] doubleValue]; + NSTimeInterval readTimeout = [[command.arguments objectAtIndex:3] doubleValue]; + bool followRedirect = [[command.arguments objectAtIndex:4] boolValue]; + NSString *responseType = [command.arguments objectAtIndex:5]; [self setRequestSerializer: @"default" forManager: manager]; [self setRequestHeaders: headers forManager: manager]; - [self setTimeout:timeoutInSeconds forManager:manager]; + [self setTimeout:readTimeout forManager:manager]; [self setRedirect:followRedirect forManager:manager]; [self setResponseSerializer:responseType forManager:manager]; @@ -205,13 +206,14 @@ NSDictionary *data = [command.arguments objectAtIndex:1]; NSString *serializerName = [command.arguments objectAtIndex:2]; NSDictionary *headers = [command.arguments objectAtIndex:3]; - NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:4] doubleValue]; - bool followRedirect = [[command.arguments objectAtIndex:5] boolValue]; - NSString *responseType = [command.arguments objectAtIndex:6]; + NSTimeInterval connectTimeout = [[command.arguments objectAtIndex:4] doubleValue]; + NSTimeInterval readTimeout = [[command.arguments objectAtIndex:5] doubleValue]; + bool followRedirect = [[command.arguments objectAtIndex:6] boolValue]; + NSString *responseType = [command.arguments objectAtIndex:7]; [self setRequestSerializer: serializerName forManager: manager]; [self setRequestHeaders: headers forManager: manager]; - [self setTimeout:timeoutInSeconds forManager:manager]; + [self setTimeout:readTimeout forManager:manager]; [self setRedirect:followRedirect forManager:manager]; [self setResponseSerializer:responseType forManager:manager]; @@ -338,12 +340,13 @@ NSDictionary *headers = [command.arguments objectAtIndex:1]; NSArray *filePaths = [command.arguments objectAtIndex: 2]; NSArray *names = [command.arguments objectAtIndex: 3]; - NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:4] doubleValue]; - bool followRedirect = [[command.arguments objectAtIndex:5] boolValue]; - NSString *responseType = [command.arguments objectAtIndex:6]; + NSTimeInterval connectTimeout = [[command.arguments objectAtIndex:4] doubleValue]; + NSTimeInterval readTimeout = [[command.arguments objectAtIndex:5] doubleValue]; + bool followRedirect = [[command.arguments objectAtIndex:6] boolValue]; + NSString *responseType = [command.arguments objectAtIndex:7]; [self setRequestHeaders: headers forManager: manager]; - [self setTimeout:timeoutInSeconds forManager:manager]; + [self setTimeout:readTimeout forManager:manager]; [self setRedirect:followRedirect forManager:manager]; [self setResponseSerializer:responseType forManager:manager]; @@ -398,11 +401,12 @@ NSString *url = [command.arguments objectAtIndex:0]; NSDictionary *headers = [command.arguments objectAtIndex:1]; NSString *filePath = [command.arguments objectAtIndex: 2]; - NSTimeInterval timeoutInSeconds = [[command.arguments objectAtIndex:3] doubleValue]; - bool followRedirect = [[command.arguments objectAtIndex:4] boolValue]; + NSTimeInterval connectTimeout = [[command.arguments objectAtIndex:3] doubleValue]; + NSTimeInterval readTimeout = [[command.arguments objectAtIndex:4] doubleValue]; + bool followRedirect = [[command.arguments objectAtIndex:5] boolValue]; [self setRequestHeaders: headers forManager: manager]; - [self setTimeout:timeoutInSeconds forManager:manager]; + [self setTimeout:readTimeout forManager:manager]; [self setRedirect:followRedirect forManager:manager]; if ([filePath hasPrefix:@"file://"]) { diff --git a/test/js-specs.js b/test/js-specs.js index 2507dd6..b52ddf3 100644 --- a/test/js-specs.js +++ b/test/js-specs.js @@ -142,12 +142,32 @@ describe('Advanced HTTP public interface', function () { it('configures global timeout value correctly with given valid value', () => { http.setRequestTimeout(10); http.getRequestTimeout().should.equal(10); + http.getConnectTimeout().should.equal(10); + http.getReadTimeout().should.equal(10); }); it('throws an Error when you try to configure global timeout with a string', () => { (() => { http.setRequestTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); }); + it('configures connect timeout and read timeout with given valid value', () => { + http.setConnectTimeout(10); + http.getConnectTimeout().should.equal(10); + }) + + it('configures connect timeout and read timeout with a string', () => { + (() => { http.setConnectTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); + }) + + it('configures read timeout and read timeout with given valid value', () => { + http.setReadTimeout(10); + http.getReadTimeout().should.equal(10); + }) + + it('configures read timeout and read timeout with a string', () => { + (() => { http.setReadTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); + }) + it('sets global option for following redirects correctly', () => { http.setFollowRedirect(false); http.getFollowRedirect().should.equal(false); @@ -375,6 +395,8 @@ describe('Common helpers', function () { serializer: 'urlencoded', followRedirect: true, timeout: 60.0, + connectTimeout: 30.0, + readTimeout: 30.0 } it('adds missing "followRedirect" option correctly', () => { diff --git a/www/global-configs.js b/www/global-configs.js index c920a9b..5eb7aa7 100644 --- a/www/global-configs.js +++ b/www/global-configs.js @@ -3,6 +3,8 @@ var globalConfigs = { serializer: 'urlencoded', followRedirect: true, timeout: 60.0, + connectTimeout: 30.0, + readTimeout: 30.0 }; module.exports = globalConfigs; diff --git a/www/helpers.js b/www/helpers.js index ecdb100..bb77c88 100644 --- a/www/helpers.js +++ b/www/helpers.js @@ -487,7 +487,9 @@ module.exports = function init(global, jsUtil, cookieHandler, messages, base64, params: checkParamsObject(options.params || {}), responseType: checkResponseType(options.responseType || validResponseTypes[0]), serializer: checkSerializer(options.serializer || globals.serializer), - timeout: checkTimeoutValue(options.timeout || globals.timeout), + connectTimeout: checkTimeoutValue(options.connectTimeout || globals.connectTimeout), + readTimeout: checkTimeoutValue(options.readTimeout || globals.readTimeout), + timeout: checkTimeoutValue(options.timeout || globals.timeout) }; } }; diff --git a/www/public-interface.js b/www/public-interface.js index 8e73d36..17fbced 100644 --- a/www/public-interface.js +++ b/www/public-interface.js @@ -14,6 +14,11 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf setRequestTimeout: setRequestTimeout, getFollowRedirect: getFollowRedirect, setFollowRedirect: setFollowRedirect, + // @Android Only + getConnectTimeout: getConnectTimeout, + setConnectTimeout: setConnectTimeout, + getReadTimeout: getReadTimeout, + setReadTimeout: setReadTimeout, // @DEPRECATED disableRedirect: disableRedirect, // @DEPRECATED @@ -95,6 +100,24 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf function setRequestTimeout(timeout) { globalConfigs.timeout = helpers.checkTimeoutValue(timeout); + globalConfigs.connectTimeout = helpers.checkTimeoutValue(timeout); + globalConfigs.readTimeout = helpers.checkTimeoutValue(timeout); + } + + function getConnectTimeout() { + return globalConfigs.connectTimeout; + } + + function setConnectTimeout(timeout) { + globalConfigs.connectTimeout = helpers.checkTimeoutValue(timeout); + } + + function getReadTimeout() { + return globalConfigs.readTimeout; + } + + function setReadTimeout(timeout) { + globalConfigs.readTimeout = helpers.checkTimeoutValue(timeout); } function getFollowRedirect() { @@ -154,18 +177,18 @@ module.exports = function init(exec, cookieHandler, urlUtil, helpers, globalConf case 'post': case 'put': case 'patch': - return helpers.processData(options.data, options.serializer, function(data) { - exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, data, options.serializer, headers, options.timeout, options.followRedirect, options.responseType]); + return helpers.processData(options.data, options.serializer, function (data) { + exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, data, options.serializer, headers, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType]); }); case 'upload': var fileOptions = helpers.checkUploadFileOptions(options.filePath, options.name); - return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, fileOptions.filePaths, fileOptions.names, options.timeout, options.followRedirect, options.responseType]); + return exec(onSuccess, onFail, 'CordovaHttpPlugin', 'uploadFiles', [url, headers, options.connectTimeout, options.readTimeout, fileOptions.filePaths, fileOptions.names, options.timeout, options.followRedirect, options.responseType]); case 'download': var filePath = helpers.checkDownloadFilePath(options.filePath); var onDownloadSuccess = helpers.injectCookieHandler(url, helpers.injectFileEntryHandler(success)); - return exec(onDownloadSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, headers, filePath, options.timeout, options.followRedirect]); + return exec(onDownloadSuccess, onFail, 'CordovaHttpPlugin', 'downloadFile', [url, headers, filePath, options.connectTimeout, options.readTimeout, options.followRedirect]); default: - return exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, headers, options.timeout, options.followRedirect, options.responseType]); + return exec(onSuccess, onFail, 'CordovaHttpPlugin', options.method, [url, headers, options.connectTimeout, options.readTimeout, options.followRedirect, options.responseType]); } } From 87ddbbe3b1012f7a485fe61c1ad635a51015e04f Mon Sep 17 00:00:00 2001 From: Moon Date: Thu, 25 Mar 2021 00:01:46 +0800 Subject: [PATCH 3/4] Update test case description --- test/js-specs.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/js-specs.js b/test/js-specs.js index b52ddf3..2c82246 100644 --- a/test/js-specs.js +++ b/test/js-specs.js @@ -150,21 +150,21 @@ describe('Advanced HTTP public interface', function () { (() => { http.setRequestTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); }); - it('configures connect timeout and read timeout with given valid value', () => { + it('configures connect timeout value correctly with given valid value', () => { http.setConnectTimeout(10); http.getConnectTimeout().should.equal(10); }) - it('configures connect timeout and read timeout with a string', () => { + it('throws an Error when you try to configure connect timeout with a string', () => { (() => { http.setConnectTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); }) - it('configures read timeout and read timeout with given valid value', () => { + it('configures read timeout value correctly with given valid value', () => { http.setReadTimeout(10); http.getReadTimeout().should.equal(10); }) - it('configures read timeout and read timeout with a string', () => { + it('throws an Error when you try to configure connect timeout with a string', () => { (() => { http.setReadTimeout('myString'); }).should.throw(messages.INVALID_TIMEOUT_VALUE); }) From 7c1836e87ffd0f19391ea7f2a35386ae753eb237 Mon Sep 17 00:00:00 2001 From: Moon Date: Thu, 25 Mar 2021 00:02:29 +0800 Subject: [PATCH 4/4] Set default connectTimeout and readTimeout as 60s --- www/global-configs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/global-configs.js b/www/global-configs.js index 5eb7aa7..7f43baa 100644 --- a/www/global-configs.js +++ b/www/global-configs.js @@ -3,8 +3,8 @@ var globalConfigs = { serializer: 'urlencoded', followRedirect: true, timeout: 60.0, - connectTimeout: 30.0, - readTimeout: 30.0 + connectTimeout: 60.0, + readTimeout: 60.0 }; module.exports = globalConfigs;