Menu

#526 curl_getdate(), DST, and cookie expiration

closed-fixed
libcurl (356)
5
2014-12-21
2005-06-30
Anonymous
No

Platform: Windows XP
libcurl: 7.14

With the system clock properly configured to
automatically adjust for Daylight Saving Time,
curl_getdate() appears to return a time_t value which
is 1 hour ahead of the correct value. This prevents
cookies from expiring at the proper time.

The following demonstrates the problem:

#include <stdio.h>
#include "curl/curl.h"

int main()
{
time_t tNow = ::time(NULL);
tm tmGMT;
char szGMT[128];

::strftime\( szGMT, 128, "%a, %d-%b-%Y %H:%M:%S GMT",

&tmGMT );

time\_t tCURL = ::curl\_getdate\(szGMT, NULL\);
time\_t tDiff = tCURL - tNow;

printf\("Current time: %s\n", szGMT\);
printf\("Sytem time\_t: %i\n", tNow\);
printf\("libcurl time\_t: %i\n", tCURL\);
printf\("Difference: %i seconds\n", tCURL - tNow\);

return 0;

}

-----------------------------------------------------------
Example run with properly configured system clock
(during DST):

Current time: Thu, 30-Jun-2005 03:02:14 GMT
Sytem time_t: 1120100534
libcurl time_t: 1120104134
Difference: 3600 seconds

-----------------------------------------------------------
Example run with automatic DST adjustment disabled:

Current time: Thu, 30-Jun-2005 03:02:28 GMT
Sytem time_t: 1120100548
libcurl time_t: 1120100548
Difference: 0 seconds

Discussion

  • Daniel Stenberg

    Daniel Stenberg - 2005-06-30

    Logged In: YES
    user_id=1110

    I'm puzzled.

    Why is "automatic DST adjustment" ? Isn't that the thing
    that automatically changes to DST at one date and then at
    another later date it again switches off DST?

    If so, how on earth can that affect the date functions like
    this?

    libcurl is simply using mktime() and gmtime(). I don't see
    how that can be wrong. To me, it looks like Windows or the c
    library you're using, is doing it wrong.

     
  • Daniel Stenberg

    Daniel Stenberg - 2005-06-30

    Logged In: YES
    user_id=1110

    Can you check what mktime() returns for this setup with and
    without auto-DST set?

    I can't but suspect that this is yet another chapter in the
    windows-DST-mess:

    http://www.codeproject.com/datetime/dstbugs.asp

     
  • Daniel Stenberg

    Daniel Stenberg - 2005-07-04

    Logged In: YES
    user_id=1110

    I don't have/use windows myself. Without assistance I can't
    solve this problem.

     
  • Gisle Vanem

    Gisle Vanem - 2005-07-05

    Logged In: YES
    user_id=47168

    Without an environment variable "TZ=GMT+1" I'm getting the
    same result. With TZ set, there is no problem and difference
    regarding system DST is set or not.

     
  • Daniel Stenberg

    Daniel Stenberg - 2005-07-05

    Logged In: YES
    user_id=1110

    Ok. Now we're getting somewhere!

    Is there any (Windows-) way we can figure out what timezone
    we're in and set the TZ variable before these time functions
    are used, if we find out it isn't already set?

    Thanks Gisle!

     
  • Gisle Vanem

    Gisle Vanem - 2005-07-05

    Logged In: YES
    user_id=47168

    Something like:
    const char *env = getenv("TZ");
    if (!env)
    putenv("TZ=GMT");

    before time() makes the difference 0.

    AFAIK, $TZ is only used by libc (msvcrt.dll). The official info
    is returned by GetTimeZoneInformation().

    http://msdn.microsoft.com/library/default.asp?url=/library/en-
    us/sysinfo/base/gettimezoneinformation.asp

    We should be able to use that (bias) in case $TZ isn't defined.

     
  • Daniel Stenberg

    Daniel Stenberg - 2005-07-05

    Logged In: YES
    user_id=1110

    Great!

    I've just committed this fix. Closing this, considered fixed.

     
  • Daniel Stenberg

    Daniel Stenberg - 2005-07-05
    • status: open --> closed-fixed
     
  • Rouslan Grabar

    Rouslan Grabar - 2006-03-14

    Logged In: YES
    user_id=866512

    const char *env = getenv("TZ");
    if(!env)
    _putenv("TZ=GMT");

    Note the underscore in _putenv. This version of putenv does
    not leak memory (7 bytes "TZ=GMT\0") when libcurl used as a
    static lib. Tested under MSVC 7.1

    :)

     
  • Martin Skinner

    Martin Skinner - 2006-11-28

    Logged In: YES
    user_id=86583
    Originator: NO

    I think this bug is still there.

    I have made extensive tests with different date-strings and TZ environment variables. The following combinations return different results on linux and windows:

    TZ=CEST (central european summer time).
    Dates are "Wed, 02 Aug 2006 14:16:26 GMT"
    "Wed, 02 Aug 2006 15:16:26 CET"
    "Wed, 02 Aug 2006 16:16:26 CEST"

    Linux returns the correct datetimes, windows is off by one hour.

    Other TZ values I tested: UTC. MEZ, UTC+2 worked correctly. So it seems to be the TZ value with summer time (dst).

    By tracing the internal values I was able to narrow down the problem to the gmtime call and the following call to mktime. The return value of mktime (t2) is off.

    On a hunch, I then changed the code to hold a copy of the gmtime return value - that seems to fixed the problem:

    #ifdef HAVE_GMTIME_R
    /* thread-safe version */
    struct tm keeptime2;
    gmt = (struct tm *)gmtime_r(&t, &keeptime2);
    if(!gmt)
    return -1; /* illegal date/time */
    t2 = mktime(gmt);
    #else
    struct tm gmt2;
    gmt = gmtime(&t); /* use gmtime_r() if available */
    if(!gmt)
    return -1; /* illegal date/time */
    gmt2 = *gmt; /* create local copy */
    t2 = mktime(&gmt2);
    #endif

    /* Add the time zone diff (between the given timezone and GMT) and the
    diff between the local time zone and GMT. */
    delta = (long)((tzoff!=-1?tzoff:0) + (t - t2));

    It looks like windows has a problem with the non-reentrant version of gmtime + mktime if TZ has a DST timezome.

    BTW: defining HAVE_GMTIME_R for windows also fixes the problem. We can probably do this too.

    And with this fix, the _putenv("TZ=GMT") hack is no longer necessary.

    Cheers,
    Martin

     
  • Daniel Stenberg

    Daniel Stenberg - 2006-11-28
    • status: closed-fixed --> open
     
  • Daniel Stenberg

    Daniel Stenberg - 2006-11-28

    Logged In: YES
    user_id=1110
    Originator: NO

    But since Windows doesn't provide the libc it really comes down to what the compiler vendors provide. Do really all windows compilers come with gmtime_r() support? If so it would certainly make sense to simply switch to using that...

     
  • Martin Skinner

    Martin Skinner - 2006-11-28

    Logged In: YES
    user_id=86583
    Originator: NO

    MSVC 2003 has gmtime_r, don't know about other compilers/runtimes.

    I think we should

    a) fix the non-reentrant code path
    b) set HAVE_GMTIME_R for MSVC 2003 and higher

    #if _MSC_VER > 1310
    #define GMTIME
    #endif

     
  • Daniel Stenberg

    Daniel Stenberg - 2006-12-05
    • status: open --> closed-fixed
     
  • Daniel Stenberg

    Daniel Stenberg - 2006-12-05

    Logged In: YES
    user_id=1110
    Originator: NO

    Many thanks for your work on this. Fix has been committed. Closing this bug report (again)!