{ "id": "154940", "key": "TIMOB-20415", "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": "16980", "description": "New V8", "name": "Release 6.0.0", "archived": false, "released": true, "releaseDate": "2016-11-15" }, { "id": "17706", "name": "Release 5.4.0", "archived": false, "released": true, "releaseDate": "2016-08-11" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-06-16T20:25:10.000+0000", "created": "2016-02-16T13:27:19.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "5.1.2", "android", "httpclient", "network" ], "versions": [ { "id": "17072", "name": "Release 5.1.2", "archived": false, "released": true, "releaseDate": "2016-01-12" }, { "id": "17993", "description": "Release 5.2.2", "name": "Release 5.2.2", "archived": false, "released": true, "releaseDate": "2016-04-05" } ], "issuelinks": [], "assignee": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "updated": "2016-06-21T22:42:19.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": "h3. Steps to Reproduce\n- Set bad credentials on Basic Auth\n\nRun attatched project with Android and you can see in console readyState = 1. In our log server we register infinite requests and the request never ends.\n\nrequest => response 401 => request => response 401\n\nWith no error callback.\n\nIn iOS its OK.\n\nh3. Actual Result\nInfinite Loop with no callback to 401 http error.\n\nh3. Expected Result\nError callback with 3 attempts like browsers or like iOS.", "attachment": [ { "id": "58248", "filename": "app.zip", "author": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "created": "2016-02-16T13:29:52.000+0000", "size": 10427729, "mimeType": "application/zip" } ], "flagged": false, "summary": "Android: HttpClient Basic Auth: Infinite loop with bad credentials", "creator": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "subtasks": [], "reporter": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "environment": null, "closedSprints": [ { "id": 641, "state": "closed", "name": "2016 Sprint 12 SDK", "startDate": "2016-06-04T00:30:28.612Z", "endDate": "2016-06-18T00:30:00.000Z", "completeDate": "2016-06-20T04:25:16.065Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "376971", "author": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "body": "Test App", "updateAuthor": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "created": "2016-02-16T13:30:21.000+0000", "updated": "2016-02-16T13:30:21.000+0000" }, { "id": "378784", "author": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "body": "What happen with this? When do you planning to fix this?", "updateAuthor": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "created": "2016-03-04T17:35:35.000+0000", "updated": "2016-03-04T17:35:35.000+0000" }, { "id": "378872", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "[~jormagar] Thanks for reporting this ticket. Will be investigating this.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-03-07T02:12:30.000+0000", "updated": "2016-03-07T02:12:30.000+0000" }, { "id": "380595", "author": { "name": "sschueller", "key": "sschueller", "displayName": "Stefan Schüller", "active": true, "timeZone": "Europe/Berlin" }, "body": "Please add a unit test for http auth, it is kind of an important core feature.\r\n\r\nFor those who need a fix now, don't use the built-in {{withCredentials}}, {{username}}, {{password}} feature in {{createHTTPClient}}. Instead set the authorization header by hand like so. Do this after {{xhr.open()}} but before {{xhr.send()}}.\r\n\r\n{code}\r\nxhr.setRequestHeader(\"Authorization\", \"Basic \" + Titanium.Utils.base64encode(username + ':' + password));\r\n{code}", "updateAuthor": { "name": "sschueller", "key": "sschueller", "displayName": "Stefan Schüller", "active": true, "timeZone": "Europe/Berlin" }, "created": "2016-03-24T10:38:22.000+0000", "updated": "2016-03-29T06:30:24.000+0000" }, { "id": "380759", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "[~sschueller] Thanks for the info. (y)", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-03-28T03:00:17.000+0000", "updated": "2016-03-28T03:00:17.000+0000" }, { "id": "385667", "author": { "name": "BBMobileDev", "key": "bbmobiledev", "displayName": "Blackbaud MobileDev", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This bug is affecting Blackbaud's primary mobile application and we need a fix ASAP! This bug is causing our users to get locked out repeatedly and is affecting our user experience rating. Please let us know when this will be fixed, I do not see a planned fixed in version yet. Thank You.", "updateAuthor": { "name": "BBMobileDev", "key": "bbmobiledev", "displayName": "Blackbaud MobileDev", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-05-13T14:07:52.000+0000", "updated": "2016-05-13T14:07:52.000+0000" }, { "id": "387244", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "[~jormagar] would you have the logs for the server when this happens? I'm trying to see if it would help in figuring out what's happening.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-06-01T05:55:20.000+0000", "updated": "2016-06-01T05:55:20.000+0000" }, { "id": "387255", "author": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "body": "Yes, i do.\r\n\r\nWhen I report the JIRA ticket someone of your team test it. Here the logs:\r\n\r\n2016-02-17 08:13:34 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 115.127.6.99 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Google+Nexus+7+-+5.1.0+-+API+22+-+800x1280;+Android+API+Level:+22;+en-US; ) - - mimaen.webs.upv.es 401 5 0 389 401 811\r\n\r\n2016-02-17 08:13:34 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 115.127.6.99 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Google+Nexus+7+-+5.1.0+-+API+22+-+800x1280;+Android+API+Level:+22;+en-US; ) ASPSESSIONIDCWSQRDST=PHKHNFBCPBFPBLNAHHAGIBEG - mimaen.webs.upv.es 401 5 0 389 495 218\r\n\r\n...\r\n\r\n2016-02-17 11:01:38 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 115.127.6.99 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Google+Nexus+7+-+5.1.0+-+API+22+-+800x1280;+Android+API+Level:+22;+en-US; ) ASPSESSIONIDCWSQRDST=OINLOFBCBNOMGEIHGJKMMCJA - mimaen.webs.upv.es 401 5 0 389 495 218\r\n\r\n2016-02-17 11:01:38 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 115.127.6.99 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Google+Nexus+7+-+5.1.0+-+API+22+-+800x1280;+Android+API+Level:+22;+en-US; ) ASPSESSIONIDCWSQRDST=PINLOFBCIJIOAJGCCGFNMIIN - mimaen.webs.upv.es 401 5 0 389 495 218\r\n\r\n \r\n*82706 requests from 115.127.6.99 (Bangladesh) after 3 hours*\r\n\r\n2016-02-18 02:28:50 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 122.11.137.25 HTTP/1.1 Appcelerator+Titanium/6.0.0+(Nexus+6;+Android+API+Level:+23;+en-US; ) - - mimaen.webs.upv.es 401 5 0 389 366 795\r\n\r\n2016-02-18 02:28:50 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 122.11.137.25 HTTP/1.1 Appcelerator+Titanium/6.0.0+(Nexus+6;+Android+API+Level:+23;+en-US; ) ASPSESSIONIDAWSSSBTS=EMABDGJCEMCDODGLLKIDDJCM - mimaen.webs.upv.es 401 5 0 389 460 421\r\n\r\n...\r\n\r\n2016-02-18 02:30:46 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 122.11.137.25 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Nexus+6;+Android+API+Level:+23;+en-US; ) ASPSESSIONIDAWSSSBTS=LOABDGJCOAJEDGMKOFCMJNHH - mimaen.webs.upv.es 401 5 0 389 460 421\r\n\r\n2016-02-18 02:30:46 W3SVC62 FENABLO 158.42.250.160 POST /error401/ platform=android 443 - 122.11.137.25 HTTP/1.1 Appcelerator+Titanium/5.1.2+(Nexus+6;+Android+API+Level:+23;+en-US; ) ASPSESSIONIDAWSSSBTS=MOABDGJCCLELCGBKDBDKPADP - mimaen.webs.upv.es 401 5 0 389 460 405\r\n\r\n*42 requests from 122.11.137.25 (Singapore) after 2 minutes*", "updateAuthor": { "name": "jormagar", "key": "jormagar", "displayName": "Jorge Macias Garcia", "active": true, "timeZone": "Europe/Brussels" }, "created": "2016-06-01T07:26:26.000+0000", "updated": "2016-06-01T07:27:23.000+0000" }, { "id": "387256", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Thank you for the logs.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-06-01T07:29:32.000+0000", "updated": "2016-06-01T07:29:32.000+0000" }, { "id": "387264", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "This seems to be quite a bad bug in Android on certain version when setting the usage of `withCredentials` property.\r\nHere's a workaround. Please use this:-\r\n\r\n{code}\r\nfunction request(event) {\r\n\r\n var client,\r\n httpConfig,\r\n url,\r\n data,\r\n credentials,\r\n forceBadCredentials;\r\n\r\n forceBadCredentials = true; //Set value to true to force bug on Android\r\n url = \"put ur url here\";\r\n credentials = {\r\n username : (forceBadCredentials) ? \"badUser\" : \"user\",\r\n password : \"p$wd\"\r\n };\r\n\r\n //Dummy post param\r\n data = {\r\n dummy : 1\r\n };\r\n\r\n httpConfig = {\r\n onload : onLoad,\r\n onerror : onError,\r\n onreadystatechange : onReadyStateChange,\r\n timeout : 3000\r\n };\r\n\r\n client = Ti.Network.createHTTPClient(httpConfig);\r\n\r\n client.open(\"POST\", url);\r\n client.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\r\n client.setRequestHeader(\"Authorization\", \"Basic \"+ Titanium.Utils.base64encode(credentials.username +':' +credentials.password));\r\n client.send(data);\r\n}\r\n{code}\r\n\r\nInstead of relying on the client to set the headers, we set the Authorization headers. This prevents the Infinite loop with bad credentials issue. {{client.setRequestHeader(\"Authorization\", \"Basic \"+ Titanium.Utils.base64encode(credentials.username +':' +credentials.password));}}\r\n\r\n[~jormagar] Please let me know if this helps in solving your issue.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-06-01T08:38:52.000+0000", "updated": "2016-06-01T08:42:04.000+0000" }, { "id": "387266", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "This workaround was mentioned earlier by [~sschueller]", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-06-01T08:46:53.000+0000", "updated": "2016-06-01T08:48:21.000+0000" }, { "id": "387930", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "PR Master: https://github.com/appcelerator/titanium_mobile/pull/8050\r\nPR 5_4_X: https://github.com/appcelerator/titanium_mobile/pull/8051\r\n\r\nFor the url, you can use either the above or run a local node server https://github.com/http-auth/http-auth/blob/master/examples/basic.js, in which case, the url is the ip of your computer. Please test on a device running Android 4.x.\r\nClassic app for test:\r\n{code}\r\n/**\r\n * onReadyStateChange\r\n * @description Debug readyState\r\n * @param {Object} event\r\n */\r\nfunction onReadyStateChange(event) {\r\n Ti.API.info(\"onReadyStateChange\");\r\n\r\n var readyState = this.readyState;\r\n\r\n switch(readyState) {\r\n case 0:\r\n // after HTTPClient declared, prior to open()\r\n // though Ti won't actually report on this readyState\r\n Ti.API.info('case 0, readyState = ' + readyState);\r\n break;\r\n case 1:\r\n // open() has been called, now is the time to set headers\r\n Ti.API.info('case 1, readyState = ' + readyState);\r\n break;\r\n case 2:\r\n // headers received, xhr.status should be available now\r\n Ti.API.info('case 2, readyState = ' + readyState);\r\n break;\r\n case 3:\r\n // data is being received, onsendstream/ondatastream being called now\r\n Ti.API.info('case 3, readyState = ' + readyState);\r\n break;\r\n case 4:\r\n // done, onload or onerror should be called now\r\n Ti.API.info('case 4, readyState = ' + readyState);\r\n Ti.API.info(\"HTTP DONE WITH STATUS TEXT: \" + this.getStatusText());\r\n break;\r\n }\r\n}\r\n\r\n/**\r\n * onLoad\r\n * @description Http Success Callback\r\n * @param {Object} event\r\n */\r\nfunction onLoad(event) {\r\n Ti.API.info(\"onLoad\");\r\n var statusCode,\r\n statusText,\r\n responseText,\r\n result;\r\n\r\n statusCode = this.getStatus();\r\n statusText = this.getStatusText();\r\n responseText = this.getResponseText();\r\n\r\n result = \"onLoad Callback - Status Code: \" + statusCode + \" - \" + \"Status Text: \" + statusText + \" - \" + \"Response Text: \" + responseText;\r\n\r\n Ti.API.info(result);\r\n}\r\n\r\n/**\r\n * onError\r\n * @description Http Error callback\r\n * @param {Object} event\r\n */\r\nfunction onError(event) {\r\n Ti.API.info(\"onError\");\r\n\r\n var statusCode,\r\n statusText,\r\n result;\r\n\r\n statusCode = this.getStatus();\r\n statusText = this.getStatusText();\r\n\r\n result = \"onError Callback - Status Code: \" + statusCode + \" - \" + \"Status Text: \" + statusText;\r\n\r\n Ti.API.info(result);\r\n}\r\n\r\nfunction request(event) {\r\n \r\n var client,\r\n httpConfig,\r\n url,\r\n data,\r\n credentials,\r\n forceBadCredentials;\r\n \r\n forceBadCredentials = true; //Set value to true to force bug on Android\r\n url = \"http://192.168.0.113:1337\";\r\n credentials = {\r\n username : (forceBadCredentials) ? \"badUser\" : \"user\",\r\n password : \"p$wd\"\r\n };\r\n \r\n //Dummy post param\r\n data = {\r\n dummy : 1\r\n };\r\n \r\n httpConfig = {\r\n onload : onLoad,\r\n onerror : onError,\r\n onreadystatechange : onReadyStateChange,\r\n withCredentials : true,\r\n username : credentials.username,\r\n password : credentials.password,\r\n timeout : 3000\r\n };\r\n \r\n client = Ti.Network.createHTTPClient(httpConfig);\r\n \r\n client.open(\"POST\", url);\r\n client.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\r\n //client.setRequestHeader(\"Authorization\", \"Basic \"+ Titanium.Utils.base64encode(credentials.username +':' +credentials.password));\r\n client.send(data);\r\n}\r\n\r\nvar win = Ti.UI.createWindow({\r\n layout: 'vertical',\r\n backgroundColor: '#fff'\r\n});\r\n\r\nwin.open();\r\nrequest();\r\n{code}", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-06-09T08:05:21.000+0000", "updated": "2016-06-09T08:13:10.000+0000" }, { "id": "388787", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix.\r\n\r\nWe get a {{401 : Unauthorized}} callback.\r\nClosing.\r\n\r\nEnvironment:\r\nAppc Studio : 4.7.0.201606150733\r\nTi SDK : 5.4.0.v20160617074028, 6.0.0.v20160621124613\r\nTi CLI : 5.0.9\r\nAlloy : 1.9.0\r\nMAC El Capitan : 10.11.4\r\nAppc NPM : 4.2.7-2\r\nAppc CLI : 5.4.0-18\r\nNode: 4.4.4\r\nNexus 6 - Android 6.0.1\r\nSamsung Galaxy S3 - Android 4.0.4", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-06-21T22:41:37.000+0000", "updated": "2016-06-21T22:42:11.000+0000" } ], "maxResults": 39, "total": 39, "startAt": 0 } } }