]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Bump automatic certificate update on Windows during builds (GH-143741)
authorŁukasz Langa <lukasz@langa.pl>
Mon, 12 Jan 2026 23:01:01 +0000 (00:01 +0100)
committerGitHub <noreply@github.com>
Mon, 12 Jan 2026 23:01:01 +0000 (00:01 +0100)
Without this, OpenSSL that we use to download external dependencies might use a stale certificate store and be unable to connect to servers. We need to use a Windows-specific HTTP client that uses CryptoAPI directly to trigger certificate updates.

We only do it on failure to avoid hitting servers twice. And we only do it once per each URL.

PCbuild/get_external.py

index 27fbc311bbc1d693cbb9e681b7af0e8e8f2a783f..494b22809e08443dbf12d33b92a00c4cc8f77d50 100755 (executable)
@@ -1,9 +1,11 @@
 #!/usr/bin/env python3
 
 import argparse
+import functools
 import os
 import pathlib
 import platform
+import subprocess
 import sys
 import tarfile
 import time
@@ -12,6 +14,27 @@ import urllib.request
 import zipfile
 
 
+@functools.cache
+def trigger_automatic_root_certificate_update(url: str, timeout: int = 30) -> None:
+    escaped_url = url.replace("'", "''")
+    try:
+        subprocess.run(
+            [
+                "powershell",
+                "-NoProfile",
+                "-Command",
+                f"Invoke-WebRequest -Uri '{escaped_url}'"
+                f" -UseBasicParsing -Method HEAD -MaximumRedirection 0"
+                f" -TimeoutSec {timeout}",
+            ],
+            check=True,
+            capture_output=True,
+            timeout=timeout + 5,
+        )
+    except (subprocess.CalledProcessError, subprocess.TimeoutExpired) as e:
+        print(e)
+
+
 def retrieve_with_retries(download_location, output_path, reporthook,
                           max_retries=7):
     """Download a file with exponential backoff retry and save to disk."""
@@ -25,6 +48,7 @@ def retrieve_with_retries(download_location, output_path, reporthook,
         except (urllib.error.URLError, ConnectionError) as ex:
             if attempt == max_retries:
                 raise OSError(f'Download from {download_location} failed.') from ex
+            trigger_automatic_root_certificate_update(download_location)
             time.sleep(2.25**attempt)
         else:
             return resp