Bug #2047

lighttpd issue with DST and If-Modified-Since

Added by optikal almost 5 years ago. Updated almost 5 years ago.

Status:FixedStart date:2009-08-05
Priority:NormalDue date:
Assignee:-% Done:

100%

Category:-
Target version:1.4.24
Missing in 1.5.x:

Description

Server is running CentOS 4.7, 2.6.9-78.0.22.ELsmp, tzdata-2009f-1.el4, lighttpd 1.4.23

example.css has a timestamp of Aug 4 18:54 EST.

curl -I -s -H "Host: example.com" -H "If-Modified-Since: Tue, 04 Aug 2009 22:25:33 GMT" GMT http://example.com/example.css
HTTP/1.1 304 Not Modified
Content-Type: text/css
Accept-Ranges: bytes
ETag: "2568490623"
Last-Modified: Tue, 04 Aug 2009 22:54:19 GMT
Content-Length: 9870
Date: Wed, 04 Aug 2009 23:20:05 GMT
Server: lighttpd

However, if you subtract 1 hour and 1 second from the last-modified date:

curl -I -s -H "Host: example.com" -H "If-Modified-Since: Tue, 04 Aug 2009 21:54:18 GMT" GMT http://example.com/example.css
HTTP/1.1 200 OK
Content-Type: text/css
Accept-Ranges: bytes
ETag: "2568490623"
Last-Modified: Tue, 04 Aug 2009 22:54:19 GMT
Content-Length: 9870
Date: Wed, 04 Aug 2009 23:25:13 GMT
Server: lighttpd

Workaround is using GMT as the server's timezone instead.

Associated revisions

Revision 2608
Added by stbuehler almost 5 years ago

Set tm.tm_isdst = 0 before mktime() (fixes #2047)

Revision 2609
Added by stbuehler almost 5 years ago

Set tm.tm_isdst = 0 before mktime() (fixes #2047)

History

#1 Updated by optikal almost 5 years ago

  • Target version set to 1.4.23

#2 Updated by optikal almost 5 years ago

Here is a clearer example:

Date set to exactly 1 hour before 'last-modified' date:

curl -I -s -H "Host: example.com" -H "If-Modified-Since: Wed, 04 Aug 2009 23:47:19 GMT" http://example.com/example.css
HTTP/1.1 304 Not Modified
Content-Type: text/css
Accept-Ranges: bytes
ETag: "1397551174"
Last-Modified: Wed, 05 Aug 2009 00:47:19 GMT
Date: Wed, 05 Aug 2009 00:47:52 GMT
Server: lighttpd

Date set to 1 hour and 1 second before last-modified date:

curl -I -s -H "Host: example.com" -H "If-Modified-Since: Wed, 04 Aug 2009 23:47:18 GMT" http://example.com/example.css
HTTP/1.1 200 OK
Content-Type: text/css
Accept-Ranges: bytes
ETag: "1397551174"
Last-Modified: Wed, 05 Aug 2009 00:47:19 GMT
Content-Length: 25
Date: Wed, 05 Aug 2009 00:47:58 GMT
Server: lighttpd

#3 Updated by stbuehler almost 5 years ago

  • Target version changed from 1.4.23 to 1.4.24

ARGS! Even after i disabled setting Target version to aready released versions in the "new issue" and "update issue" form people still don't get it -.-

#4 Updated by stbuehler almost 5 years ago

I think your strptime overrides tm_isdst (or mktime is broken); you could try setting it to 0 again after strptime (src/http-header-glue.c line 334), before mktime.

#5 Updated by optikal almost 5 years ago

I added `tm.tm_isdst = 0;' just before t_header = mktime(&tm);, recompiled and same issue as before.

#6 Updated by stbuehler almost 5 years ago

mktime changes tm_isdst; that behaviour isn't documented in the manpage, and wrong imho:
(posix: http://www.opengroup.org/onlinepubs/009695399/functions/mktime.html)

Upon successful completion, the values of the tm_wday and tm_yday components of the structure shall be set appropriately, and the other components are set to represent the specified time since the Epoch, but with their values forced to the ranges indicated in the <time.h> entry; the final value of tm_mday shall not be set until tm_mon and tm_year are determined.

As the tm_isdst field is "within the range" (no range specified, but all values are "valid" as their interpretation is specified), i don't see a reason to change it.

In eglibc (used in debian), strptime sets tm_isdst to zero, so you don't see the problem there.

The solution is to add tm.tm_isdst = 0 before every call to mktime.

#7 Updated by optikal almost 5 years ago

That solution does indeed work. Thanks!

#8 Updated by stbuehler almost 5 years ago

  • Status changed from New to Fixed
  • % Done changed from 0 to 100

Applied in changeset r2608.

Also available in: Atom