1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Tomato cookies expire too quickly

Discussion in 'Tomato Firmware' started by blackwind, Apr 16, 2013.

  1. blackwind

    blackwind Serious Server Member

    In Tomato (all mods), cookies have a maximum expiration date of one month, with most expiring after just 24 hours. Why should I have to reapply all my preferred view preferences every day? Why aren't these cookies set to expire in 2038?
     
  2. koitsu

    koitsu Network Guru Member

    Can you be more specific when you say "cookies"? What exact preferences are you talking about? I need specific technical details to be able to verify and find relevant bits in the code. If you could provide a step-by-step reproduction method for the issue I'd appreciate it.
     
  3. blackwind

    blackwind Serious Server Member

    Head to, for example, IP Traffic > Transfer Rates and tick "Ignore inactive hosts". Tomato saves your preference in a cookie called "tomato_ipt_details_onlyactive", which expires in 24 hours. If you don't want inactive hosts to appear, you have to keep ticking that box once a day, every day. Some of these cookies do last longer than others (up to a month), but I see no valid reason for them to expire at all.
     
  4. koitsu

    koitsu Network Guru Member

    I have no such feature on my router. Firmware: tomato-K26USB-1.28.0502.1MIPSR2Toastman-RT-N-Ext.trx.

    I may have such features disabled intentionally, so please provide another setting/location of a "cookie" that I can look at.

    And cookies should expire, by the way (indefinite cookies = bad, as they eventually can cause problems with browsers). But I would happily agree upon something like 365 days.
     
  5. blackwind

    blackwind Serious Server Member

    The last active submenu item is saved in "tomato_menu_ipt", "tomato_menu_bwm", etc. Launching your browser's cookie manager and filtering by "tomato_" will bring up the works.

    As long as a cookie's expiration date isn't set beyond January 18th, 2038, no browser will ever choke on it. January 18th, 2038 is indefinite enough for my tastes.
     
  6. koitsu

    koitsu Network Guru Member

    So here are some details as of this writing:

    1. I can confirm the existence of cookies, and which names they have vary what features you have enabled in your router, and what menus you've visited. The most common two are tomato_menu_status and tomato_status_overview_refresh. However there are all kinds of other "dynamic" cookies, ones ending in -error for example, and so on.

    2. The cookies are not set via HTTP server headers (i.e. they aren't set using httpd), but rather are set via Javascript using cookie.set (some kind of class I haven't looked at yet). The Javascript in question is tomato.js.

    3. The expiry time for these cookies changes constantly and is based on a whole bunch of hullabaloo which looks very broken/wrong. It's based on (are you ready?) an arbitrary calculated "refresh time" for the page (e.g. those "dynamic content reloads" you see on pages like Status -> Overview).

    4. The expires= content used (reference for what I'm talking about) seems to be based on... hell, I can't even discern what it's based on reliably, because the code is so badly formatted it's hard to follow. Look at tomato.js and search for expires= and see if you can work out what the hell. :) Haha.

    The calculation method/model varies all over the place, and since the code is not commented and single-letter variable names are used everywhere, it's very hard to follow.

    This looks to me like another wonderful thing to add to my ever-growing list of tomato.js brokenness.

    Fixing this is not easy, and furthermore, I'm not sure this is fixable given that we aren't sure what the copyright/licensing ordeal is with Jonathan Zarate and the Javascript bits (Toastman et al, can you correct me on this?).
     
  7. blackwind

    blackwind Serious Server Member

    It appears that changing this...
    Code:
    var cookie = {
    set: function(key, value, days) {
    document.cookie = 'tomato_' + key + '=' + value + '; expires=' +
    (new Date(new Date().getTime() + ((days ? days : 14) * 86400000))).toUTCString() + '; path=/';
    },
    ...to this...
    Code:
    var cookie = {
    set: function(key, value, days) {
    document.cookie = 'tomato_' + key + '=' + value + '; expires=' +
    new Date(2147483647000).toUTCString() + '; path=/';
    },
    ...would be sufficient. It's easier to simply ignore the "days" parameter (why is it even there in the first place?) than try to make out what the author was smoking when he wrote this mess. ;)

    EDIT: Implemented my fix with mount --bind /jffs/tomato.js /www/tomato.js, and it worked like a charm.
     
  8. blackwind

    blackwind Serious Server Member

    Just came across a related issue: In QoS > View Details, the "Exclude gateway traffic" option doesn't persist at all.

    EDIT: ...and the solution to that is to enable "Avoid displaying LAN to router connections" in Administration > Debugging. A counterintuitive solution, to be sure, but a solution nonetheless.
     
  9. Toastman

    Toastman Super Moderator Staff Member Member

    I'm in agreement there are many little things in Tomato that would be better fixed. My take on the licensing, which was reached in conjunction with Teddy bear some while back, is that the GUI is sacrosanct territory, and any changes should reflect that. The rest of it, I'd regard as pretty much open-source, I don't believe Jonathan would have any problem with these things being fixed.
     
  10. koitsu

    koitsu Network Guru Member

    So I thought on this for a while, and did some research as well.

    My proposal was to simply increase the cookie expiry from 14 days to 365 days. However, this introduces a problem many years in the future -- for example, if we had them last 365 days (from the time the cookie is created), this would present problems during, say, March of 2037 since the expiry time of March 2038 would would wrap past the end of the timecounter (in January 2038) and thus start claiming to be slightly past the epoch (specifically March 1970).

    There's no way to "officially" make a cookie indefinite other than set a hard-coded timestamp like what blackwind has proposed. Reference material: http://stackoverflow.com/questions/3290424/set-a-cookie-to-never-expire

    Because of that, I'm on the verge of saying "let's go with his solution" but would like a comment added above the var definition to explain what the "magic number" 2147483647000 is. Mathematically, it's: ((2^31)-1)*1000. 2^31 = the maximum value of a 32-bit unsigned integer (equates to UNIX timestamp 2147483648) minus 1 second, times 1000 (to get milliseconds, which is the value Javascript Date() wants).

    So I think this would suffice:

    Code:
    // The value 2147483647000 is ((2^31)-1)*1000, which is the number of
    // milliseconds (minus 1 second) which correlates with the year 2038 counter
    // rollover. This effectively makes the cookie never expire.
    var cookie = {
    set: function(key, value, days) {
    document.cookie = 'tomato_' + key + '=' + value + '; expires=' +
    new Date(2147483647000).toUTCString() + '; path=/';
    },
    
    I can provide a git diff against the Toastman-RT-N branch if you want, Toastman -- I'm not sure though if this should go into the Tomato-1.28 branch or not (I'm still not fully up to speed on what changes go where for this stuff).
     
  11. blackwind

    blackwind Serious Server Member

    Long-term, we should certainly be aiming for a fully commented (and properly indented) codebase, so I don't object, per se -- it just comes at the cost of 207 bytes in a distribution that's already hurting for space. Go ahead with the diff, but if there's to be further development on tomato.js, someone should begin exploring that JavaScript-packer-in-the-makefile idea that was suggested in the other thread sooner rather than later.
    Tomato-1.28, I would assume. That way, it'll end up in Shibby and Victek as well.

    Then again, when one assumes...
     
  12. BikeHelmet

    BikeHelmet Networkin' Nut Member

    Get a better browser.


    This has been annoying the crap out of me for over half a year. Every time I check my bandwidth usage, I have to flip from KB to GB to make the stupid huge numbers readable. I would VERY MUCH like it to save my settings forever.

    Cookie problems only seem to affect IE, Chrome, and Safari, so I'd say go for it.

    Yes! You've made at least one board member happy today.

    Honestly, cookie expiry should be implemented/overrideable at the browser level. There are some forums that force me to sign in every few days. (like this one) I just find that annoying, and I'm not nearly as active on boards that do that. I do wish there was a way to force certain cookies to not ever expire until 2038. Although some forums are not designed for it, many are designed for it and just pick arbitrary amounts of time.

    A PHPBB one that I visit sporadically keeps me signed in for 3 months... then it logs me out. If I use an addon to restore the cookies, I am logged back in... therefore, there's no reason to sign me out in the first place. If my browser gave me options of 14 days, 365 days, and 2038, that'd make me happy.
     
  13. Victek

    Victek Network Guru Member

    No problem, added to my code.

    Thanks!
     
    Elfew likes this.
  14. blackwind

    blackwind Serious Server Member

    After poking around to see what exactly it takes to build my own configuration pages, I decided to take this one step further and clean up some sloppy code that, eventually, would've lead some developer somewhere to some serious head-scratching:
    Code:
    var cookie = {
    // The value 2147483647000 is ((2^31)-1)*1000, which is the number of
    // milliseconds (minus 1 second) which correlates with the year 2038 counter
    // rollover. This effectively makes the cookie never expire.
    set: function(key, value, days) {
    document.cookie = 'tomato_' + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '; expires=' +
    new Date(2147483647000).toUTCString() + '; path=/';
    },
    get: function(key) {
    var r = ('; ' + document.cookie + ';').match('; tomato_' + encodeURIComponent(key) + '=(.*?);');
    return r ? decodeURIComponent(r[1]) : null;
    },
    unset: function(key) {
    document.cookie = 'tomato_' + encodeURIComponent(key) + '=; expires=' +
    (new Date(1)).toUTCString() + '; path=/';
    }
    };
    By escaping and unescaping passed values as needed, we eliminate the risk of cookies bleeding into one another.

    Tested and confirmed working. I recommend all mod authors update.
     

Share This Page