Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-17573] iOS: Unable to Set Multiple Cookies in Request Header

GitHub Issuen/a
TypeBug
PriorityHigh
StatusClosed
ResolutionFixed
Resolution Date2015-06-02T21:02:37.000+0000
Affected Version/sn/a
Fix Version/sRelease 4.1.0
ComponentsiOS
LabelsSDK3.3.0, httpclient
ReporterShuo Liang
AssigneeEric Merriman
Created2014-08-29T03:35:17.000+0000
Updated2017-03-31T22:25:40.000+0000

Description

IOS: Fail to Set Multiple Cookie in Request Header for Ti.Network.HTTPClient in SDK 3.3.0

Reproduce and Test Case:

var sessionid = Ti.App.getSessionId();
var token = "example_token";
var contextid = '1234567';
var endpoint = "http://127.0.0.1:8888";
//Ti.API.info(endpoint);

var loader = Titanium.Network.createHTTPClient({
     onload : function(e) {
         Ti.API.info("Received text: " + this.responseText);
         alert("Received text: " + this.responseText);
         alert('success');
     },
     onerror : function(e) {
         Ti.API.debug(e.error);
         alert('error');
     },
     timeout : 5000  // in milliseconds
}); 

loader.open("GET", endpoint);
loader.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); 
loader.setRequestHeader('User-Agent', Titanium.userAgent); 
loader.setRequestHeader('Cookie', 'Context='+contextid); 
loader.setRequestHeader('Cookie', 'sessionID='+sessionid);
loader.setRequestHeader('Cookie', 'Auth_token='+token); 
loader.send(); 

Expect Result:

Server host can get all three cookie information. For example:
Context=1234567; sessionID=486E0EFB-C4A1-478A-9A5B-A9EB683B310C; Auth_token=example_token

Actual Result:

Only the last cookie has been passed to server. For example:
Auth_token=example_token
It 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. N.B. Only happens in 3.3.0.GA. It works well in 3.2.3 and 3.2.1.

Attachments

FileDateSize
cookieTest.js2014-08-29T03:39:37.000+0000501
cookieTest2.js2015-05-13T06:04:16.000+0000573

Comments

  1. Shuo Liang 2014-08-29

    Attached a simple nodejs server to get cookie information from http request.
  2. Ingo Muschenetz 2014-08-29

    As a workaround, can you set them as a single call?
  3. Pedro Enrique 2014-08-29

    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. Here's the workaround for the meantime
       loader.setRequestHeader('Cookie', 'Context='+contextid+';sessionID='+sessionid+';Auth_token='+token); 
       
  4. Shuo Liang 2014-09-04

    Sorry, Please ignore my last comment, as choosing wrong version of SDK. the workaround works well in SDK 3.3.0
  5. kosso 2014-11-11

    This is still happening in 3.4.0.GA Also, clearCookies() does not appear to be working any more. Has the ASI Library been deprecated? Is this why these changes have occurred? Does 'APSHTTPClient' handles all the Ti.Network.HTTPClient methods now?
  6. Jon Alter 2015-03-12

    This should not be fixed. It is working as it should. We should update the docs with Pedro's solution
  7. Ingo Muschenetz 2015-03-12

    See http://stackoverflow.com/questions/1268673/set-a-request-header-in-javascript for a reference.
  8. Chee Kiat Ng 2015-05-07

    Advised to use workaround described by Pedro for issues like this.
  9. Ingo Muschenetz 2015-05-07

    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.
  10. Chee Kiat Ng 2015-05-08

    PR Here: https://github.com/appcelerator/titanium_mobile/pull/6827 and PR Here: https://github.com/appcelerator/APSHTTPClient/pull/23 Mutliple 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.
  11. Chee Kiat Ng 2015-05-12

    [~pec1985], To address your github comments for the PR. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#setRequestHeader() According 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._ and [~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). Here is another link that shows an example for setting the same header twice: http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method and the abstracted sample code here:
        // The following script:
        var client = new XMLHttpRequest();
        client.open('GET', 'demo.cgi');
        client.setRequestHeader('X-Test', 'one');
        client.setRequestHeader('X-Test', 'two');
        client.send();
        
        // …results in the following header being sent:
        X-Test: one, two
        
    If it's agreed that we follow the web-like behavior, I will proceed to work on the Android portion.
  12. Chee Kiat Ng 2015-05-13

    After further research from earlier links, these links and the native SDK references: https://github.com/AliSoftware/OHHTTPStubs/issues/43 http://www.tutorialspoint.com/http/http_header_fields.htm http://blog.hjoseph.com/post/93171041261/setting-nsmutableurlrequest-cookies It is concluded that:

    repeated calls to setRequestHeader appends the field values

    if the field is cookie, append is done with ';', while other fields use ','

    new sample code:

        var sessionid = Ti.App.getSessionId();
        var token = "example_token";
        var contextid = '1234567';
        var endpoint = "http://127.0.0.1:8888";
         
        var loader = Titanium.Network.createHTTPClient({
             onload : function(e) {
                 Ti.API.info("Received text: " + this.responseText);
                 alert("Received text: " + this.responseText);
                 alert('success');
             },
             onerror : function(e) {
                 Ti.API.debug(e.error);
                 alert('error');
             },
             timeout : 5000  // in milliseconds
        }); 
         
        loader.open("GET", endpoint);
        loader.setRequestHeader('Content-Type', 'application/json;charset=utf-8'); 
        loader.setRequestHeader('User-Agent', Titanium.userAgent); 
        loader.setRequestHeader('Accept', 'text/plain; q=0.5');
        loader.setRequestHeader('Accept', 'text/html');
        loader.setRequestHeader('Cookie', 'Context='+contextid); 
        loader.setRequestHeader('Cookie', 'sessionID='+sessionid);
        loader.setRequestHeader('Cookie', 'Auth_token='+token); 
        
        loader.send(); 
        

    expected result (seen on from cookieTest2.js attached)

        Context=1234567; sessionID=1202D4C5-98E0-4968-8118-9335936C2E79; Auth_token=example_token
        request header is
        { host: '127.0.0.1:8888',
          'x-titanium-id': '25FE4B6E-7DA9-4344-B55B-25195570860F',
          'x-requested-with': 'XMLHttpRequest',
          accept: 'text/plain; q=0.5, text/html',
          'content-type': 'application/json;charset=utf-8',
          cookie: 'Context=1234567; sessionID=1202D4C5-98E0-4968-8118-9335936C2E79; Auth_token=example_token',
          'accept-language': 'en-us',
          'accept-encoding': 'gzip, deflate',
          connection: 'keep-alive',
          '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;)' }
        
  13. Chee Kiat Ng 2015-05-13

    iOS APSHttpClient PR: https://github.com/appcelerator/APSHTTPClient/pull/25 iOS Master PR: https://github.com/appcelerator/titanium_mobile/pull/6844 android PR coming soon.
  14. Ashraf Abu 2015-05-13

    Android PR: https://github.com/appcelerator/titanium_mobile/pull/6845
  15. Pedro Enrique 2015-06-01

    Reopening, reason: Waiting for android PR to be merged
  16. Lee Morris 2017-03-31

    Closing ticket as fixed, if there are any problems, please file a new ticket.

JSON Source