{ "id": "159837", "key": "TIMOB-23282", "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": [], "resolution": { "id": "7", "description": "", "name": "Invalid" }, "resolutiondate": "2016-04-28T04:46:15.000+0000", "created": "2016-04-26T21:33:49.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [ "android", "fileupload", "httpclient" ], "versions": [], "issuelinks": [], "assignee": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "updated": "2017-03-22T21:45:38.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": [], "description": "Having some issues with Android file upload where the key in my payload is an integer.\r\n\r\nSample code to reproduce, taken from Ti API HttpClient file upload docs:\r\n\r\n{code:java}\r\nTitanium.Media.openPhotoGallery({\r\n success: function(event) {\r\n\t var xhr = Titanium.Network.createHTTPClient();\r\n\t xhr.onload = function(e) {\r\n\t Ti.UI.createAlertDialog({\r\n\t title: 'Success',\r\n\t message: 'status code ' + this.status\r\n\t }).show();\r\n\t };\r\n xhr.open('POST', 'REQUESTBI.N URL');\r\n\t xhr.send({1: event.media});\r\n }\r\n});\r\n{code}\r\n\r\n1. Create a Requestbi.n url and replace it in the .open()\r\n2. run this on an Android device. You should receive the following error, specifying that the int key cannot be cast to a string, and you will not be able to upload the file to requestbin.\r\n\r\n[WARN] : W/System.err: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String\r\n[WARN] : W/System.err: \tat ti.modules.titanium.network.TiHTTPClient.send(TiHTTPClient.java:1012)\r\n[WARN] : W/System.err: \tat ti.modules.titanium.network.HTTPClientProxy.send(HTTPClientProxy.java:154)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Function.nativeInvoke(Native Method)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Function.callSync(V8Function.java:57)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Function.call(V8Function.java:43)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.runtime.v8.V8Function$1.run(V8Function.java:70)\r\n[WARN] : W/System.err: \tat android.os.Handler.handleCallback(Handler.java:739)\r\n[WARN] : W/System.err: \tat android.os.Handler.dispatchMessage(Handler.java:95)\r\n[WARN] : W/System.err: \tat android.os.Looper.loop(Looper.java:145)\r\n[WARN] : W/System.err: \tat org.appcelerator.kroll.KrollRuntime$KrollRuntimeThread.run(KrollRuntime.java:118)\r\n\r\n3. as suggested by AppC support, change the .send() to\r\n\r\n{code:java}\r\nxhr.send(JSON.stringify({1: event.media}));\r\n{code}\r\n\r\nthis will fire and upload to requestbin, however if you look at the response in requestbin, the event.media is a json string and not a binary object.\r\n\r\n4. change the .send() to\r\n\r\n{code:java}\r\nvar payload = {};\r\nvar key = '\\\"' + 1 + '\\\"';\r\npayload[key] = event.media;\r\nxhr.send(payload);\r\n{code}\r\n\r\nthis will post the photo and be received as a binary object in requestbin.\r\n\r\nI have witnessed this for Android only. IOS seems to handle things ok, and I can post the object without having to do any additional processing.\r\n\r\nI am posting to an API that has been used by our native Android developers, and they are sending the key as an integer. I believe that the Titanium SDK is somehow tripping over the integer to string conversion\r\n\r\nPlease let me know if you need any more info.\r\n\r\nThanks\r\nEric", "attachment": [], "flagged": false, "summary": "HttpClient file upload, Android, int as key in payload causes java.lang.Integer cannot be cast to java.lang.String", "creator": { "name": "capsizeno4", "key": "capsizeno4", "displayName": "eric harms", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "capsizeno4", "key": "capsizeno4", "displayName": "eric harms", "active": true, "timeZone": "America/Los_Angeles" }, "environment": "OSX Yosemite 10.10.5\r\nMacbook pro Mid 2015\r\nTi SDK 5.2.2.GA\r\nAndroid device, tested on multiple different devices > 4.2", "comment": { "comments": [ { "id": "384050", "author": { "name": "nsalahin", "key": "nsalahin", "displayName": "Nazmus Salahin", "active": true, "timeZone": "Asia/Dhaka" }, "body": "Hello,\r\nI am able to reproduce this issue.\r\n*Steps:*\r\n1. Create a default classic project.\r\n2. Replace the code in app.js with following.\r\n{code}\r\nvar win1 = Titanium.UI.createWindow({\r\n\ttitle : 'Tab 1',\r\n\tbackgroundColor : '#fff'\r\n});\r\n\r\nvar label1 = Titanium.UI.createLabel({\r\n\tcolor : '#999',\r\n\ttext : 'I am Window 1',\r\n\tfont : {\r\n\t\tfontSize : 20,\r\n\t\tfontFamily : 'Helvetica Neue'\r\n\t},\r\n\ttextAlign : 'center',\r\n\twidth : 'auto'\r\n});\r\n\r\nlabel1.addEventListener(\"click\", function(e) {\r\n\tTitanium.Media.openPhotoGallery({\r\n\r\n\t\tsuccess : function(event) {\r\n\r\n\t\t\tvar xhr = Titanium.Network.createHTTPClient();\r\n\r\n\t\t\txhr.onload = function(e) {\r\n\r\n\t\t\t\tTi.UI.createAlertDialog({\r\n\r\n\t\t\t\t\ttitle : 'Success',\r\n\r\n\t\t\t\t\tmessage : 'status code ' + this.status\r\n\r\n\t\t\t\t}).show();\r\n\r\n\t\t\t};\r\n\r\n\t\t\txhr.open('POST', 'test');\r\n\r\n\t\t\txhr.send({\r\n\t\t\t\t1 : event.media\r\n\t\t\t});\r\n\r\n\t\t}\r\n\t});\r\n\r\n});\r\n\r\nwin1.add(label1);\r\n\r\nwin1.open(); \r\n\r\n\r\n{code}\r\n3. Build and run the app.\r\n4. Click the label. >> Gallery will be opened\r\n5. Select any photo from the gallery. >> Following error log is produced.\r\n[Screenshot|http://s32.postimg.org/g0tei0q11/android.png]\r\n{code}\r\n[ERROR] : TiExceptionHandler: (main) [47622,47622] ----- Titanium Javascript Runtime Error -----\r\n[ERROR] : TiExceptionHandler: (main) [0,47622] - In ti:/httpclient.js:28,9\r\n[ERROR] : TiExceptionHandler: (main) [0,47622] - Message: Uncaught Error: java.lang.Integer cannot be cast to java.lang.String\r\n[ERROR] : TiExceptionHandler: (main) [1,47623] - Source: \t\t_send.call(this, options);\r\n[ERROR] : V8Exception: Exception occurred at ti:/httpclient.js:28: Uncaught Error: java.lang.Integer cannot be cast to java.lang.String\r\n{code}\r\n\r\n \r\nThanks\r\n\r\n*Environment*:\r\n\r\n*Device info:* Nexus7 (android 6.0.1)\r\n*Node.js Version:* 0.12.7\r\n*npm Version:* 2.11.3\r\n*Titanium SDKs:* 5.2.2.GA and 5.2.1.GA\r\n*Java Development Kit Version:* 1.8.0_73\r\n*Titanium CLI Version:* 5.0.5\r\n*Appcelerator CLI Version:* 5.2.2\r\n*Appcelerator Studio:* 4.5.0", "updateAuthor": { "name": "nsalahin", "key": "nsalahin", "displayName": "Nazmus Salahin", "active": true, "timeZone": "Asia/Dhaka" }, "created": "2016-04-27T08:51:02.000+0000", "updated": "2016-04-27T08:51:02.000+0000" }, { "id": "384149", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "[~eric.harms@gmail.com] So I believe, based on point 4\r\n{code}\r\nvar payload = {};\r\nvar key = '\\\"' + 1 + '\\\"';\r\npayload[key] = event.media;\r\nxhr.send(payload);\r\n{code}\r\nThis is the workaround you are using on Android?", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-04-28T04:35:57.000+0000", "updated": "2016-04-28T04:35:57.000+0000" }, { "id": "384150", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Based on https://tools.ietf.org/html/rfc7159\r\n{quote}\r\nAn object is an unordered collection of zero or more name/value\r\npairs, where a name is a string and a value is a string, number,\r\nboolean, null, object, or array.\r\n{quote}\r\n\r\nMost JSON doc would agree that the key used is a String.\r\nAdditional info: http://www.json.org/\r\n\r\nHence, I would say that this not an issue/bug.\r\n\r\nIn order to insert the key as a number, you could handle it by making it into a string.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-04-28T04:45:34.000+0000", "updated": "2016-04-28T04:47:57.000+0000" }, { "id": "384151", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "I'm resolving this ticket as invalid.", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2016-04-28T04:46:35.000+0000", "updated": "2016-04-28T04:46:35.000+0000" }, { "id": "415034", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as invalid with reference to previous comments.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-22T21:45:38.000+0000", "updated": "2017-03-22T21:45:38.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }