{ "id": "135880", "key": "TIMOB-17573", "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": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2015-06-02T21:02:37.000+0000", "created": "2014-08-29T03:35:17.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "SDK3.3.0", "httpclient" ], "versions": [], "issuelinks": [], "assignee": { "name": "emerriman", "key": "emerriman", "displayName": "Eric Merriman ", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-31T22:25:40.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": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "h6.IOS: Fail to Set Multiple Cookie in Request Header for Ti.Network.HTTPClient in SDK 3.3.0\r\n\r\n\r\nh6.Reproduce and Test Case:\r\n{code:title=app.js}\r\nvar sessionid = Ti.App.getSessionId();\r\nvar token = \"example_token\";\r\nvar contextid = '1234567';\r\nvar endpoint = \"http://127.0.0.1:8888\";\r\n//Ti.API.info(endpoint);\r\n\r\nvar loader = Titanium.Network.createHTTPClient({\r\n onload : function(e) {\r\n Ti.API.info(\"Received text: \" + this.responseText);\r\n alert(\"Received text: \" + this.responseText);\r\n alert('success');\r\n },\r\n onerror : function(e) {\r\n Ti.API.debug(e.error);\r\n alert('error');\r\n },\r\n timeout : 5000 // in milliseconds\r\n}); \r\n\r\nloader.open(\"GET\", endpoint);\r\nloader.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); \r\nloader.setRequestHeader('User-Agent', Titanium.userAgent); \r\nloader.setRequestHeader('Cookie', 'Context='+contextid); \r\nloader.setRequestHeader('Cookie', 'sessionID='+sessionid);\r\nloader.setRequestHeader('Cookie', 'Auth_token='+token); \r\nloader.send(); \r\n{code}\r\n\r\nh6.Expect Result:\r\nServer host can get all three cookie information.\r\nFor example:\r\n{code}\r\nContext=1234567; sessionID=486E0EFB-C4A1-478A-9A5B-A9EB683B310C; Auth_token=example_token\r\n{code} \r\n\r\nh6.Actual Result:\r\nOnly the last cookie has been passed to server.\r\nFor example:\r\n{code}\r\nAuth_token=example_token\r\n{code}\r\n\r\nIt seems like the previous cookies property will be overwritten by the next when you set multiple cookies information at one request header on SDK 3.3.0.GA. \r\n\r\nN.B. Only happens in 3.3.0.GA. It works well in 3.2.3 and 3.2.1. ", "attachment": [ { "id": "50852", "filename": "cookieTest.js", "author": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "created": "2014-08-29T03:39:37.000+0000", "size": 501, "mimeType": "text/javascript" }, { "id": "55359", "filename": "cookieTest2.js", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-13T06:04:16.000+0000", "size": 573, "mimeType": "application/x-javascript" } ], "flagged": false, "summary": "iOS: Unable to Set Multiple Cookies in Request Header", "creator": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "subtasks": [], "reporter": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "environment": "Titanium SDK 3.3.0.GA\r\nIOS 7.0", "closedSprints": [ { "id": 407, "state": "closed", "name": "2015 Sprint 11 SDK", "startDate": "2015-05-23T00:00:08.253Z", "endDate": "2015-06-06T00:00:00.000Z", "completeDate": "2015-06-08T16:18:16.381Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "320940", "author": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "body": "Attached a simple nodejs server to get cookie information from http request.", "updateAuthor": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "created": "2014-08-29T03:39:37.000+0000", "updated": "2014-08-29T03:39:37.000+0000" }, { "id": "321029", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "As a workaround, can you set them as a single call?", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2014-08-29T15:41:48.000+0000", "updated": "2014-08-29T15:41:48.000+0000" }, { "id": "321095", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "The internal headers are a key dictionary where the first param is the key and the second the value. Setting a second cookie will replace the previous.\r\nHere's the workaround for the meantime\r\n{code}\r\nloader.setRequestHeader('Cookie', 'Context='+contextid+';sessionID='+sessionid+';Auth_token='+token); \r\n{code}", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2014-08-29T20:29:31.000+0000", "updated": "2015-03-12T23:37:42.000+0000" }, { "id": "321698", "author": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "body": "Sorry, Please ignore my last comment, as choosing wrong version of SDK. the workaround works well in SDK 3.3.0", "updateAuthor": { "name": "sliang", "key": "sliang", "displayName": "Shuo Liang", "active": true, "timeZone": "Asia/Harbin" }, "created": "2014-09-04T00:25:19.000+0000", "updated": "2014-09-04T00:25:19.000+0000" }, { "id": "331557", "author": { "name": "kosso", "key": "kosso", "displayName": "kosso", "active": true, "timeZone": "Europe/London" }, "body": "This is still happening in 3.4.0.GA \r\n\r\nAlso, clearCookies() does not appear to be working any more. \r\n\r\nHas the ASI Library been deprecated? Is this why these changes have occurred? Does 'APSHTTPClient' handles all the Ti.Network.HTTPClient methods now?\r\n", "updateAuthor": { "name": "kosso", "key": "kosso", "displayName": "kosso", "active": true, "timeZone": "Europe/London" }, "created": "2014-11-11T11:26:41.000+0000", "updated": "2014-11-11T11:26:41.000+0000" }, { "id": "345895", "author": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "body": "This should not be fixed. It is working as it should. We should update the docs with Pedro's solution", "updateAuthor": { "name": "jalter", "key": "jalter", "displayName": "Jon Alter", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-03-12T23:25:15.000+0000", "updated": "2015-03-12T23:25:15.000+0000" }, { "id": "345897", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "See http://stackoverflow.com/questions/1268673/set-a-request-header-in-javascript for a reference.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-03-12T23:38:32.000+0000", "updated": "2015-03-12T23:38:32.000+0000" }, { "id": "351888", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Advised to use workaround described by Pedro for issues like this.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-07T02:32:31.000+0000", "updated": "2015-05-07T02:32:31.000+0000" }, { "id": "351926", "author": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "body": "No, this is not working as it should If you view the StackOverflow post, we are created a web-influenced API. Thus, we should adopt a web-like behavior, and you can set multiple cookies in the browser. Apologies if this wasn't clear before, but I do think we _should_ fix this.", "updateAuthor": { "name": "ingo", "key": "ingo", "displayName": "Ingo Muschenetz", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2015-05-07T13:21:42.000+0000", "updated": "2015-05-07T13:21:42.000+0000" }, { "id": "351994", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "PR Here: https://github.com/appcelerator/titanium_mobile/pull/6827\r\nand PR Here: https://github.com/appcelerator/APSHTTPClient/pull/23\r\n\r\nMutliple calls to setRequestHeader on the 'Cookie' key, will result in the values being appended with a ';' in between each value, instead of one replacing the other.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-08T05:29:32.000+0000", "updated": "2015-05-08T05:29:32.000+0000" }, { "id": "352244", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "[~pec1985], To address your github comments for the PR.\r\nhttps://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader()\r\nAccording to this abstracted from the link, _if this method is called several times with the same header, the values are merged into one single request header._\r\nand [~ingo]'s comment that we should follow a web-influenced API and adopt a web-like behavior, we can only use *setRequestHeader* and *not* create another method called *addRequestHeader* (although i would have preferred the latter option as well). \r\nHere is another link that shows an example for setting the same header twice:\r\nhttp://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method\r\nand the abstracted sample code here:\r\n{code}\r\n// The following script:\r\nvar client = new XMLHttpRequest();\r\nclient.open('GET', 'demo.cgi');\r\nclient.setRequestHeader('X-Test', 'one');\r\nclient.setRequestHeader('X-Test', 'two');\r\nclient.send();\r\n\r\n// …results in the following header being sent:\r\nX-Test: one, two\r\n{code} \r\n\r\nIf it's agreed that we follow the web-like behavior, I will proceed to work on the Android portion.\r\n", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-12T08:21:36.000+0000", "updated": "2015-05-12T08:21:36.000+0000" }, { "id": "352393", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "After further research from earlier links, these links and the native SDK references:\r\nhttps://github.com/AliSoftware/OHHTTPStubs/issues/43\r\nhttp://www.tutorialspoint.com/http/http_header_fields.htm\r\nhttp://blog.hjoseph.com/post/93171041261/setting-nsmutableurlrequest-cookies\r\n\r\nIt is concluded that:\r\n# repeated calls to setRequestHeader appends the field values\r\n# if the field is cookie, append is done with ';', while other fields use ','\r\n\r\nh4. new sample code:\r\n{code}\r\nvar sessionid = Ti.App.getSessionId();\r\nvar token = \"example_token\";\r\nvar contextid = '1234567';\r\nvar endpoint = \"http://127.0.0.1:8888\";\r\n \r\nvar loader = Titanium.Network.createHTTPClient({\r\n onload : function(e) {\r\n Ti.API.info(\"Received text: \" + this.responseText);\r\n alert(\"Received text: \" + this.responseText);\r\n alert('success');\r\n },\r\n onerror : function(e) {\r\n Ti.API.debug(e.error);\r\n alert('error');\r\n },\r\n timeout : 5000 // in milliseconds\r\n}); \r\n \r\nloader.open(\"GET\", endpoint);\r\nloader.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); \r\nloader.setRequestHeader('User-Agent', Titanium.userAgent); \r\nloader.setRequestHeader('Accept', 'text/plain; q=0.5');\r\nloader.setRequestHeader('Accept', 'text/html');\r\nloader.setRequestHeader('Cookie', 'Context='+contextid); \r\nloader.setRequestHeader('Cookie', 'sessionID='+sessionid);\r\nloader.setRequestHeader('Cookie', 'Auth_token='+token); \r\n\r\nloader.send(); \r\n{code}\r\n\r\nh4. expected result (seen on from cookieTest2.js attached)\r\n{code}\r\nContext=1234567; sessionID=1202D4C5-98E0-4968-8118-9335936C2E79; Auth_token=example_token\r\nrequest header is\r\n{ host: '127.0.0.1:8888',\r\n 'x-titanium-id': '25FE4B6E-7DA9-4344-B55B-25195570860F',\r\n 'x-requested-with': 'XMLHttpRequest',\r\n accept: 'text/plain; q=0.5, text/html',\r\n 'content-type': 'application/json;charset=utf-8',\r\n cookie: 'Context=1234567; sessionID=1202D4C5-98E0-4968-8118-9335936C2E79; Auth_token=example_token',\r\n 'accept-language': 'en-us',\r\n 'accept-encoding': 'gzip, deflate',\r\n connection: 'keep-alive',\r\n 'user-agent': 'Appcelerator Titanium/0.0.0 (iPhone Simulator/8.3; iPhone OS; en_US;), Appcelerator Titanium/0.0.0 (iPhone Simulator/8.3; iPhone OS; en_US;)' }\r\n{code}", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-13T05:42:35.000+0000", "updated": "2015-05-13T05:42:35.000+0000" }, { "id": "352396", "author": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "body": "iOS APSHttpClient PR: https://github.com/appcelerator/APSHTTPClient/pull/25\r\niOS Master PR: https://github.com/appcelerator/titanium_mobile/pull/6844\r\n\r\nandroid PR coming soon.", "updateAuthor": { "name": "cng", "key": "cng", "displayName": "Chee Kiat Ng", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-05-13T06:14:38.000+0000", "updated": "2015-05-13T06:14:38.000+0000" }, { "id": "352398", "author": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "body": "Android PR: https://github.com/appcelerator/titanium_mobile/pull/6845", "updateAuthor": { "name": "msamah", "key": "msamah", "displayName": "Ashraf Abu", "active": false, "timeZone": "Asia/Singapore" }, "created": "2015-05-13T06:23:49.000+0000", "updated": "2015-05-13T06:23:49.000+0000" }, { "id": "354038", "author": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Reopening, reason: Waiting for android PR to be merged", "updateAuthor": { "name": "penrique", "key": "penrique", "displayName": "Pedro Enrique", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2015-06-01T22:39:37.000+0000", "updated": "2015-06-01T22:39:37.000+0000" }, { "id": "416598", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed, if there are any problems, please file a new ticket.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-31T22:25:40.000+0000", "updated": "2017-03-31T22:25:40.000+0000" } ], "maxResults": 17, "total": 17, "startAt": 0 } } }