[web] kill GMTOFFSET (closes #2154655)

Its last user, set_cookie(expires=...), can just as well interpret its argument as UTC. Naïve datetime objects with an implicit non-UTC timezone are just awful.

authorJulien Cristau <julien.cristau@logilab.fr>
changeset937deb71a681
branchdefault
phasepublic
hiddenno
parent revision#b6c55274135a [web/request] don't play tricks with utc offset
child revision#ea73a949e802 [debian] Add a Breaks for cubicweb-folder which stills use GMTOFFSET
files modified by this revision
doc/3.21.rst
web/httpcache.py
web/request.py
# HG changeset patch
# User Julien Cristau <julien.cristau@logilab.fr>
# Date 1426520794 -3600
# Mon Mar 16 16:46:34 2015 +0100
# Node ID 937deb71a681045f9f84b72e5388a8718114ead6
# Parent b6c55274135aa46a82f4dd274146db48acec490b
[web] kill GMTOFFSET (closes #2154655)

Its last user, set_cookie(expires=...), can just as well interpret its
argument as UTC. Naïve datetime objects with an implicit non-UTC
timezone are just awful.

diff --git a/doc/3.21.rst b/doc/3.21.rst
@@ -7,10 +7,18 @@
1  The cubicweb.web.views.timeline module (providing the timeline-json, timeline
2  and static-timeline views) has moved to a standalone cube_
3 
4  .. _cube: https://www.cubicweb.org/project/cubicweb-timeline
5 
6 +API changes
7 +-----------
8 +
9 +* req.set_cookie's "expires" argument, if not None, is expected to be a
10 +  date or a datetime in UTC.  It was previously interpreted as localtime
11 +  with the UTC offset the server started in, which was inconsistent (we
12 +  are not aware of any users of that API).
13 +
14  Deprecated code drops
15  ---------------------
16 
17  * the user_callback api has been removed; people should use plain
18    ajax functions instead
diff --git a/web/httpcache.py b/web/httpcache.py
@@ -20,14 +20,10 @@
19  __docformat__ = "restructuredtext en"
20 
21  from time import mktime
22  from datetime import datetime
23 
24 -# time delta usable to convert localized time to GMT time
25 -# XXX this become erroneous after a DST transition!!!
26 -GMTOFFSET = - (datetime.now() - datetime.utcnow())
27 -
28  class NoHTTPCacheManager(object):
29      """default cache manager: set no-cache cache control policy"""
30      def __init__(self, view):
31          self.view = view
32          self.req = view._cw
diff --git a/web/request.py b/web/request.py
@@ -43,11 +43,11 @@
33  from cubicweb.uilib import remove_html_tags, js
34  from cubicweb.utils import SizeConstrainedList, HTMLHead, make_uid
35  from cubicweb.view import TRANSITIONAL_DOCTYPE_NOEXT
36  from cubicweb.web import (INTERNAL_FIELD_VALUE, LOGGER, NothingToEdit,
37                            RequestError, StatusResponse)
38 -from cubicweb.web.httpcache import GMTOFFSET, get_validators
39 +from cubicweb.web.httpcache import get_validators
40  from cubicweb.web.http_headers import Headers, Cookie, parseDateTime
41 
42  _MARKER = object()
43 
44  def build_cb_uid(seed):
@@ -534,12 +534,12 @@
45              expires = maxage + time.time()
46          elif expires:
47              # we don't want to handle times before the EPOCH (cause bug on
48              # windows). Also use > and not >= else expires == 0 and Cookie think
49              # that means no expire...
50 -            assert expires + GMTOFFSET > date(1970, 1, 1)
51 -            expires = timegm((expires + GMTOFFSET).timetuple())
52 +            assert expires > date(1970, 1, 1)
53 +            expires = timegm(expires.timetuple())
54          else:
55              expires = None
56          # make sure cookie is set on the correct path
57          cookie = Cookie(str(name), str(value), self.base_url_path(),
58                          expires=expires, secure=secure, httponly=httponly)