{ "id": "147497", "key": "TIMOB-18870", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "16723", "description": "Windows Platform Support, ListView updates, Vector overlays in maps", "name": "Release 4.1.0", "archived": false, "released": true, "releaseDate": "2015-07-08" } ], "resolution": { "id": "10000", "description": "", "name": "Done" }, "resolutiondate": "2015-05-14T04:43:21.000+0000", "created": "2015-05-04T21:12:41.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [], "versions": [ { "id": "16593", "description": "Release 4.0.0", "name": "Release 4.0.0", "archived": false, "released": true, "releaseDate": "2015-05-21" } ], "issuelinks": [], "assignee": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "updated": "2017-03-16T21:41:55.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "h6.Issue Description\r\nWhen an user submits, in the 'load' event of the webview, document download functionality is initiated an completed. Contents are written to a file and fetched back and displayed in the webview. We are facing the below issues in android (works fine in iOS): \r\n\r\n1. When calling HTTPClient document is not properly downloaded. The actual size of the document is around 10MB while the downloaded size is around 6KB \r\n2. If the document download is initiated once, the login screen doesn’t render on the mobile app until we re-install the app. We have also tried to disable cache.\r\n\r\nAlso a forbidden error occurs only when trying from within the app. If you hit the same url from Chrome browser, it works with the credentials used. \r\n\r\nh6.Use Case\r\nTo download a remote document. The remote url will first render a Login screen; after successful login, the same url will render the actual document. \r\n\r\nh6.Android 4.0.4 device output:\r\n{code}\r\n05-04 15:27:03.398: I/TiAPI(9530): 0.35535908174344655\r\n05-04 15:27:03.398: I/TiAPI(9530): 0.8045602605863192\r\n05-04 15:27:03.437: I/TiAPI(9530): 1\r\n05-04 15:27:03.447: I/TiAPI(9530): onload called, readyState = 4\r\n05-04 15:27:03.447: I/TiAPI(9530): download file onload\r\n{code}\r\n\r\nh6.Android 4.4.4 device output:\r\n{code}\r\n05-04 15:48:41.077: I/TiAPI(7104): 1\r\n05-04 15:48:41.079: I/TiAPI(7104): onload called, readyState = 4\r\n05-04 15:48:41.079: I/TiAPI(7104): download file onload\r\n{code}\r\n\r\nh6.iOS 8.2 device output:\r\n{code}\r\n[DEBUG] New scheme: { URL: https://keysight-preprod.assetserv.com/das/UI/Login }\r\n[DEBUG] New scheme: { URL: https://keysight-preprod.assetserv.com/r2/servlet/dload/Leveraging-Big-Data.pdf?force_dload=true&confirm_license=true&id=4977 }\r\n[INFO] webViewonload - else\r\n[INFO] download file\r\n{code}\r\n\r\nh6.Test Case\r\nWhen we open the link it will ask for login, the login username and password it's been set automatically. Just hit the login button. Then the content will be downloaded fully and open. \r\n{code}\r\nvar win = Ti.UI.createWindow();\r\nwin.addEventListener('open', function() {\r\n downloadKF();\r\n});\r\nvar testWebView = Ti.UI.createWebView({\r\n height : Ti.UI.FILL,\r\n width : Ti.UI.FILL\r\n});\r\ntestWebView.addEventListener('load', webViewonload);\r\ntestWebView.addEventListener('error', webViewOnError);\r\nwin.add(testWebView);\r\nwin.open();\r\n\r\nvar loggedin = false;\r\nfunction downloadKF(e) {\r\n testWebView.url = url;\r\n}\r\n\r\nfunction autoLoginUser() {\r\n if (_emailID && _password) {\r\n testWebView.evalJS(\"document.getElementById('IDToken1').value = '\" + _emailID + \"'\");\r\n testWebView.evalJS(\"document.getElementById('IDToken2').value = '\" + _password + \"'\");\r\n testWebView.evalJS(\"LoginSubmit('Log In')\");\r\n loggedin = true;\r\n }\r\n}\r\n\r\nfunction webViewonload(e) {\r\n if (loggedin == false) {\r\n Ti.API.info('onload ' + e.source.html);\r\n setTimeout(function(e) {\r\n Ti.API.info('called autologin');\r\n autoLoginUser();\r\n }, 5);\r\n\r\n } else {\r\n Ti.API.info('webViewonload - else');\r\n setTimeout(function(e) {\r\n downloadFile();\r\n }, 1000);\r\n\r\n }\r\n}\r\n\r\nfunction webViewOnError(e) {\r\n Ti.API.info(' e.error code ' + e.errorCode);\r\n if (e.errorCode == -1015) {\r\n var _errorText = 'Incomplete download. \\n(Error details: ' + e.message + ', Error code: ' + e.errorCode + '). \\nPage will refresh.';\r\n reloadInASecondWithMessage(_errorText);\r\n }\r\n}\r\n\r\nfunction reloadInASecondWithMessage(errorText) {\r\n testWebView.html = errorText;\r\n setTimeout(function incompleteMessageHandler() {\r\n testWebView.url = url;\r\n }, 1000);\r\n}\r\n\r\nfunction downloadFile() {\r\n Ti.API.info('download file');\r\n var xhr = Titanium.Network.createHTTPClient({\r\n onload : function(e) {\r\n Ti.API.info('onload called, readyState = ' + this.readyState);\r\n Ti.API.info('download file onload');\r\n if (Ti.Filesystem.isExternalStoragePresent()) {\r\n sdPath = 'file:///sdcard/';\r\n var folder = Ti.Filesystem.getFile(sdPath, 'Testing');\r\n if (!folder.exists()) {\r\n folder.createDirectory();\r\n }\r\n newPath = 'file:///sdcard/Testing/' + fileName;\r\n tmpFile = Ti.Filesystem.getFile(newPath);\r\n tmpFile.write(this.responseData);\r\n openFile();\r\n } else {\r\n alert('No external storage present');\r\n }\r\n },\r\n timeout : 50000,\r\n onerror : function(e) {\r\n Ti.API.info('Error: ' + JSON.stringify(e));\r\n },\r\n ondatastream : function(e) {\r\n Ti.API.info(e.progress);\r\n }\r\n });\r\n xhr.open('GET', url);\r\n xhr.send();\r\n}\r\n\r\nfunction openFile() {\r\n var tmpFile = Ti.Filesystem.getFile('file:///sdcard/Testing/' + fileName);\r\n if (tmpFile.exists()) {\r\n Ti.API.info('tempfile: ' + tmpFile + ' ___ ' + JSON.stringify(tmpFile));\r\n testWebView.backgroundColor = 'red';\r\n testWebView.setData(tmpFile.nativePath);\r\n } else {\r\n Ti.API.info('File not found');\r\n }\r\n}\r\n{code}", "attachment": [], "flagged": false, "summary": "Android: HTTPClient Onload Callback handles GET request incorrectly", "creator": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "egomez", "key": "egomez", "displayName": "Eduardo Gomez", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "TiSDK 3.5.1.GA & 4.0.0.RC\r\nAndroid 4.0.4 & 4.4.4\r\niOS 8.3", "closedSprints": [ { "id": 404, "state": "closed", "name": "2015 Sprint 10 SDK", "startDate": "2015-05-09T00:00:53.391Z", "endDate": "2015-05-23T00:00:00.000Z", "completeDate": "2015-05-25T14:55:16.386Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "352504", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "h6.Test Case Solution\r\nPlease provide ur credentials, url, _emailID, _password and filename\r\n{code}\r\nvar win = Ti.UI.createWindow();\r\nwin.addEventListener('open', function() {\r\n downloadKF();\r\n});\r\n\r\nvar testWebView = Ti.UI.createWebView({\r\n height : Ti.UI.FILL,\r\n width : Ti.UI.FILL\r\n});\r\n\r\n//For Android\r\n//Website didn't load again as webview was directed to the PDF link and webviews don't show that\r\n//The cookies need to be removed to show the login page again\r\nif(Ti.Platform.osname == 'android') {\r\n\tTitanium.Network.removeAllSystemCookies();\r\n}\r\n\r\ntestWebView.addEventListener('load', webViewonload);\r\ntestWebView.addEventListener('error', webViewOnError);\r\nwin.add(testWebView);\r\nwin.open();\r\n \r\nvar loggedin = false;\r\nfunction downloadKF(e) {\r\n testWebView.url = url;\r\n}\r\n \r\nfunction autoLoginUser() {\r\n if (_emailID && _password) {\r\n testWebView.evalJS(\"document.getElementById('IDToken1').value = '\" + _emailID + \"'\");\r\n testWebView.evalJS(\"document.getElementById('IDToken2').value = '\" + _password + \"'\");\r\n testWebView.evalJS(\"LoginSubmit('Login');\");\r\n loggedin = true;\r\n }\r\n}\r\n \r\nfunction webViewonload(e) {\r\n if (loggedin == false) {\r\n Ti.API.info('onload ' + e.source.html);\r\n setTimeout(function(e) {\r\n Ti.API.info('called autologin');\r\n autoLoginUser();\r\n }, 5);\r\n \r\n } else {\r\n Ti.API.info('webViewonload - else');\r\n setTimeout(function(e) {\r\n downloadFile();\r\n }, 1000);\r\n \r\n\r\n \r\n }\r\n}\r\n \r\nfunction webViewOnError(e) {\r\n Ti.API.info(' e.error code ' + e.errorCode);\r\n if (e.errorCode == -1015) {\r\n var _errorText = 'Incomplete download. \\n(Error details: ' + e.message + ', Error code: ' + e.errorCode + '). \\nPage will refresh.';\r\n reloadInASecondWithMessage(_errorText);\r\n }\r\n}\r\n \r\nfunction reloadInASecondWithMessage(errorText) {\r\n testWebView.html = errorText;\r\n setTimeout(function incompleteMessageHandler() {\r\n testWebView.url = url;\r\n }, 1000);\r\n}\r\n \r\nfunction downloadFile() {\r\n Ti.API.info('download file');\r\n\t\r\n\t//Login information in cookies needed for Android\r\n var cookies = testWebView.evalJS(\"document.cookie\"); \r\n\t \r\n var xhr = Titanium.Network.createHTTPClient({\r\n \tcache: false,\r\n onload : function(e) {\r\n Ti.API.info('onload called, readyState = ' + this.readyState);\r\n Ti.API.info('download file onload');\r\n if (Ti.Filesystem.isExternalStoragePresent()) {\r\n sdPath = 'file:///sdcard/';\r\n var folder = Ti.Filesystem.getFile(sdPath, 'Testing');\r\n if (!folder.exists()) {\r\n folder.createDirectory();\r\n }\r\n newPath = 'file:///sdcard/Testing/' + fileName;\r\n tmpFile = Ti.Filesystem.getFile(newPath);\r\n tmpFile.write(this.responseData);\r\n Ti.API.info('responseData:' + this.responseData);\r\n Ti.API.info('responseText:' + this.responseText);\r\n Ti.API.info('status:' + this.status);\r\n Ti.API.info('statusText:' + this.statusText);\r\n Ti.API.info('allResponseHeaders:' + this.allResponseHeaders);\r\n Ti.API.info('cache:' + this.cache);\r\n openFile();\r\n } else {\r\n alert('No external storage present');\r\n }\r\n },\r\n timeout : 50000,\r\n onerror : function(e) {\r\n Ti.API.info('Error: ' + JSON.stringify(e));\r\n },\r\n ondatastream : function(e) {\r\n Ti.API.info('Datastream:' +e.progress);\r\n }\r\n });\r\n \r\n //If it is Android, the cookies from webview is not shared in\r\n //Httpclient. You need to set it for the login information\r\n if(Ti.Platform.osname == 'android') {\r\n\t\tTi.API.info(\"check cookie:\"+cookies);\r\n \txhr.setRequestHeader(\"cookie\", cookies);\r\n\t}\r\n\r\n xhr.open('GET', url);\r\n xhr.send();\r\n}\r\n \r\nfunction openFile() {\r\n var tmpFile = Ti.Filesystem.getFile('file:///sdcard/Testing/' + fileName);\r\n if (tmpFile.exists()) {\r\n Ti.API.info('tempfile: ' + tmpFile + ' ___ ' + JSON.stringify(tmpFile));\r\n testWebView.backgroundColor = 'red';\r\n testWebView.setData(tmpFile.nativePath);\r\n } else {\r\n Ti.API.info('File not found');\r\n }\r\n}\r\n{code}\r\n\r\nh6.Explanation\r\nFrom http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.WebView\r\n{quote}\r\nOn Android, the web view uses the system cookie store which does not share cookies with the Titanium.Network.HTTPClient cookie store. \r\n{quote}\r\n\r\nThis implies that you need to handle the login cookies yourself. In iOS it's handled. Hence when you try to download it with the HTTPClient in the original code, you are actually just downloading the webpage, hence the 6KB file. When you set the cookie, it then does the download.\r\n\r\nThe webview is blank when you open the app again due to the webview cookies logging you in automatedly and trying to download the pdf. The webview doesn't handle the download, hence a blank screen is shown. To remove this, you need to clear the webview cookies as show in the code above.\r\n\r\nThis should solve your issues. :)", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2015-05-14T04:42:56.000+0000", "updated": "2015-05-14T04:42:56.000+0000" }, { "id": "413159", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Can confirm that this was done.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-16T21:41:55.000+0000", "updated": "2017-03-16T21:41:55.000+0000" } ], "maxResults": 3, "total": 3, "startAt": 0 } } }