cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curl-tracker mailing list Archives

[ curl-Bugs-1230118 ] curl_getdate(), DST, and cookie expiration

From: SourceForge.net <noreply_at_sourceforge.net>
Date: Tue, 28 Nov 2006 03:00:19 -0800

Bugs item #1230118, was opened at 2005-06-30 05:27
Message generated for change (Comment added) made by bagder
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=1230118&group_id=976

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: libcurl
Group: wrong behaviour
>Status: Open
>Resolution: None
Priority: 5
Private: No
Submitted By: Nobody/Anonymous (nobody)
Assigned to: Daniel Stenberg (bagder)
Summary: curl_getdate(), DST, and cookie expiration

Initial Comment:
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];

        ::memcpy(&tmGMT, ::gmtime(&tNow), sizeof(tm));
        ::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

----------------------------------------------------------------------

>Comment By: Daniel Stenberg (bagder)
Date: 2006-11-28 12:00

Message:
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...

----------------------------------------------------------------------

Comment By: Martin Skinner (mskinner)
Date: 2006-11-28 11:41

Message:
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

----------------------------------------------------------------------

Comment By: Rouslan Grabar (russ777)
Date: 2006-03-14 20:31

Message:
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

:)

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2005-07-05 16:58

Message:
Logged In: YES
user_id=1110

Great!

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

----------------------------------------------------------------------

Comment By: Gisle Vanem (giva)
Date: 2005-07-05 16:47

Message:
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.

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2005-07-05 15:54

Message:
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!

----------------------------------------------------------------------

Comment By: Gisle Vanem (giva)
Date: 2005-07-05 13:48

Message:
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.

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2005-07-04 23:03

Message:
Logged In: YES
user_id=1110

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

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2005-06-30 16:31

Message:
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

----------------------------------------------------------------------

Comment By: Daniel Stenberg (bagder)
Date: 2005-06-30 08:12

Message:
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.

----------------------------------------------------------------------

You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=100976&aid=1230118&group_id=976
Received on 2006-11-28

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET