commit:     4b57307865cf4bcde8ef5150303eb48465a43689
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sun Sep 14 09:02:46 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Sep 14 09:33:11 2025 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=4b573078

_urlopen: fix timestamp comparison by using UTC consistently

In bintree.py's _populate_remote, we call http_to_timestamp on the
timestamp header we get from the remote binhost. Unfortunately, that uses
mktime() which is documented to return *local time*:

> This is the inverse function of localtime(). Its argument is the struct_time 
> or
> full 9-tuple (since the dst flag is needed; use -1 as the dst flag if it is 
> unknown)
> which expresses the time in local time, not UTC.

Switch to using mktime_tz and parsedate_tz which operate in UTC instead. I've
changed timestamp_to_http as well just to be safe: I think this may fix
a potential issue with the value we send for If-Modified-Since, as
datetime.fromtimestamp() gives localtime.

This was manifesting as a warning with --getbinpkg:

> [gentoobinhost] WARNING: Service distfiles.gentoo.org did not respect 
> If-Modified-Since.
>  Consider asking the service operator to enable support for If-Modified-Since 
> or
>  using another service (local: 2025-09-12T12:43:46+01:00, remote: 
> 2025-09-12T11:43:46+01:00).

... which would disappear when using TZ=UTC.

Bug: https://bugs.gentoo.org/962832
Part-of: https://github.com/gentoo/portage/pull/1467
Closes: https://github.com/gentoo/portage/pull/1467
Signed-off-by: Sam James <sam <AT> gentoo.org>

 lib/portage/util/_urlopen.py | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/lib/portage/util/_urlopen.py b/lib/portage/util/_urlopen.py
index 72801b43ba..68403037ce 100644
--- a/lib/portage/util/_urlopen.py
+++ b/lib/portage/util/_urlopen.py
@@ -3,8 +3,7 @@
 
 import io
 from datetime import datetime
-from time import mktime
-from email.utils import formatdate, parsedate
+from email.utils import formatdate, parsedate_tz, mktime_tz
 from urllib.request import urlopen as _urlopen
 import urllib.parse as urllib_parse
 import urllib.request as urllib_request
@@ -68,12 +67,12 @@ def urlopen(url, timeout=10, if_modified_since=None, 
headers={}, proxies=None):
 
 def timestamp_to_http(timestamp):
     dt = datetime.fromtimestamp(float(int(timestamp) + TIMESTAMP_TOLERANCE))
-    stamp = mktime(dt.timetuple())
+    stamp = mktime_tz(dt.timetuple())
     return formatdate(timeval=stamp, localtime=False, usegmt=True)
 
 
 def http_to_timestamp(http_datetime_string):
-    timestamp = mktime(parsedate(http_datetime_string))
+    timestamp = mktime_tz(parsedate_tz(http_datetime_string))
     return str(int(timestamp))
 
 

Reply via email to