IQ.Pilot Release Commit @ 4521b0f
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz",
|
||||
"hash": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6",
|
||||
"hash_raw": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6",
|
||||
"size": 3282256,
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz",
|
||||
"hash": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9",
|
||||
"hash_raw": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9",
|
||||
"size": 98124,
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/abl-556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee.img.xz",
|
||||
"hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
|
||||
"hash_raw": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
|
||||
"size": 274432,
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz",
|
||||
"hash": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788",
|
||||
"hash_raw": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788",
|
||||
"size": 184364,
|
||||
@@ -45,7 +45,7 @@
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz",
|
||||
"hash": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585",
|
||||
"hash_raw": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585",
|
||||
"size": 40336,
|
||||
@@ -56,7 +56,7 @@
|
||||
},
|
||||
{
|
||||
"name": "splash",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/splash-993d7fb8ddfa552bd7f60e8a78b8735efbc716a0978682ed3c92fa0d694528d2.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/splash-993d7fb8ddfa552bd7f60e8a78b8735efbc716a0978682ed3c92fa0d694528d2.img.xz",
|
||||
"hash": "993d7fb8ddfa552bd7f60e8a78b8735efbc716a0978682ed3c92fa0d694528d2",
|
||||
"hash_raw": "993d7fb8ddfa552bd7f60e8a78b8735efbc716a0978682ed3c92fa0d694528d2",
|
||||
"size": 34226176,
|
||||
@@ -67,7 +67,7 @@
|
||||
},
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/boot-aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb.img.xz",
|
||||
"hash": "aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb",
|
||||
"hash_raw": "aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb",
|
||||
"size": 18216960,
|
||||
@@ -78,18 +78,14 @@
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b.img.xz",
|
||||
"hash": "a7bec67c4fef85c66736e74ee8828cbef320f3729f72fee6bea4c97f23dc8b70",
|
||||
"hash_raw": "37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/system-44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa.img.xz",
|
||||
"hash": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"hash_raw": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"size": 6291456000,
|
||||
"sparse": true,
|
||||
"sparse": false,
|
||||
"full_check": false,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "f678dbc0ffb12e49e6b561ce58d84d3831dc7b7a595909f653b330ecec9c2c65",
|
||||
"alt": {
|
||||
"hash": "37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b.img",
|
||||
"size": 6291456000
|
||||
}
|
||||
"ondevice_hash": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"url_parts": 10
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
yxhDP2ieuolHlsCLh4gOQFHFGBIZ5TcewAlO8qo+F3L13hp4K0N5vniN5ZsC7K7Lg6z4TtehTycFb5o4IIIRBA==
|
||||
IE+GKvyryxGDx98VImAM+UaqOPcs+mzWtlVs7r0h4Va2Tb9glgFBFlpaB3Btll+QI5zoo/tMlDrj463kaYQQBg==
|
||||
|
||||
@@ -39,6 +39,81 @@ IQPILOT_MANIFEST_PUBLIC_KEY = bytes.fromhex("40ae3f81b77506ecc4982a1ca37ba1d6f87
|
||||
|
||||
AGNOS_MANIFEST_FILE = "system/hardware/tici/agnos.json"
|
||||
|
||||
LFS_POINTER_MAGIC = b"version https://git-lfs"
|
||||
|
||||
|
||||
def _image_auth_module():
|
||||
"""Return the git_remote auth module, or None. On IQ.OS this comes through the
|
||||
verified loader; on stock AGNOS (an AGNOS->IQ.OS upgrade) that loader is not
|
||||
present, but the compiled bundle IS in every checkout -- import it directly."""
|
||||
try:
|
||||
from iqpilot.system.proprietary_runtime._verified_import import import_verified_module
|
||||
return import_verified_module("iqpilot_updater_private", "iqpilot_private.updater.git_remote")
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
root = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
|
||||
bundle_python = os.path.join(root, "artifacts", "iqpilot_updater_private", "python")
|
||||
if os.path.isdir(bundle_python):
|
||||
if bundle_python not in sys.path:
|
||||
sys.path.insert(0, bundle_python)
|
||||
import importlib
|
||||
return importlib.import_module("iqpilot_private.updater.git_remote")
|
||||
except Exception:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _download_headers(url: str) -> dict:
|
||||
mod = _image_auth_module()
|
||||
if mod is not None:
|
||||
try:
|
||||
headers = mod.os_image_headers(url)
|
||||
if headers:
|
||||
return headers
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
from iqpilot.common.git_creds import get_credentials
|
||||
creds = get_credentials()
|
||||
if creds and all(creds) and "/iq.lvbs/iqos" in url.lower():
|
||||
return {"Authorization": "Basic " + base64.b64encode(f"{creds[0]}:{creds[1]}".encode()).decode()}
|
||||
except Exception:
|
||||
pass
|
||||
return {}
|
||||
|
||||
|
||||
def _open_image_response(url: str) -> requests.Response:
|
||||
"""GET an image URL; when the server answers with a Git-LFS pointer (the image
|
||||
repo stores partitions as LFS objects and its raw endpoint does not resolve
|
||||
them), follow it through the LFS batch API using the same credentials."""
|
||||
auth = _download_headers(url)
|
||||
req = requests.get(url, stream=True, headers={'Accept-Encoding': None, **auth}, timeout=60)
|
||||
req.raise_for_status()
|
||||
if int(req.headers.get('content-length') or 0) >= 1024:
|
||||
return req
|
||||
|
||||
body = req.content
|
||||
if not body.startswith(LFS_POINTER_MAGIC):
|
||||
raise requests.exceptions.InvalidURL(f"unexpected tiny response ({len(body)} bytes) for {url}")
|
||||
meta = dict(line.split(" ", 1) for line in body.decode().strip().splitlines() if " " in line)
|
||||
oid = meta["oid"].split(":", 1)[1]
|
||||
size = int(meta["size"])
|
||||
|
||||
batch_url = url.split("/raw/", 1)[0] + ".git/info/lfs/objects/batch"
|
||||
batch = requests.post(batch_url,
|
||||
data=json.dumps({"operation": "download", "transfers": ["basic"],
|
||||
"objects": [{"oid": oid, "size": size}]}),
|
||||
headers={"Content-Type": "application/vnd.git-lfs+json",
|
||||
"Accept": "application/vnd.git-lfs+json", **auth},
|
||||
timeout=60)
|
||||
batch.raise_for_status()
|
||||
action = batch.json()["objects"][0]["actions"]["download"]
|
||||
req = requests.get(action["href"], stream=True,
|
||||
headers={'Accept-Encoding': None, **action.get("header", {})}, timeout=60)
|
||||
req.raise_for_status()
|
||||
return req
|
||||
|
||||
|
||||
def verify_manifest_signature(manifest_path: str) -> None:
|
||||
sig_path = f"{manifest_path}.sig"
|
||||
@@ -54,11 +129,34 @@ def verify_manifest_signature(manifest_path: str) -> None:
|
||||
public_key.verify(signature, digest)
|
||||
|
||||
|
||||
class _ChainedParts:
|
||||
"""Response-like wrapper streaming N sequential part files as one body.
|
||||
|
||||
The image host caps single uploads well below the system image size, so big
|
||||
images are stored as `<name>.pNN` LFS objects; devices re-join them here."""
|
||||
|
||||
def __init__(self, urls: list[str]) -> None:
|
||||
self.urls = urls
|
||||
self.req: requests.Response | None = None
|
||||
|
||||
def raise_for_status(self) -> None:
|
||||
if self.req is not None:
|
||||
self.req.raise_for_status()
|
||||
|
||||
def iter_content(self, chunk_size: int) -> Generator[bytes, None, None]:
|
||||
for u in self.urls:
|
||||
self.req = _open_image_response(u)
|
||||
yield from self.req.iter_content(chunk_size=chunk_size)
|
||||
|
||||
|
||||
class StreamingDecompressor:
|
||||
def __init__(self, url: str) -> None:
|
||||
def __init__(self, url: str, parts: int = 0) -> None:
|
||||
self.buf = b""
|
||||
|
||||
self.req = requests.get(url, stream=True, headers={'Accept-Encoding': None}, timeout=60)
|
||||
if parts > 1:
|
||||
self.req = _ChainedParts([f"{url}.p{i:02d}" for i in range(parts)])
|
||||
else:
|
||||
self.req = _open_image_response(url)
|
||||
self.it = self.req.iter_content(chunk_size=1024 * 1024)
|
||||
self.decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_AUTO)
|
||||
self.eof = False
|
||||
@@ -196,7 +294,7 @@ def clear_partition_hash(target_slot_number: int, partition: dict) -> None:
|
||||
|
||||
def extract_compressed_image(target_slot_number: int, partition: dict, cloudlog):
|
||||
path = get_partition_path(target_slot_number, partition)
|
||||
downloader = StreamingDecompressor(partition['url'])
|
||||
downloader = StreamingDecompressor(partition['url'], parts=int(partition.get('url_parts', 0)))
|
||||
|
||||
with open(path, 'wb+') as out:
|
||||
# Flash partition
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[
|
||||
{
|
||||
"name": "xbl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz",
|
||||
"hash": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6",
|
||||
"hash_raw": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6",
|
||||
"size": 3282256,
|
||||
@@ -12,7 +12,7 @@
|
||||
},
|
||||
{
|
||||
"name": "xbl_config",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz",
|
||||
"hash": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9",
|
||||
"hash_raw": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9",
|
||||
"size": 98124,
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
{
|
||||
"name": "abl",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz",
|
||||
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||
"size": 274432,
|
||||
@@ -34,7 +34,7 @@
|
||||
},
|
||||
{
|
||||
"name": "aop",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz",
|
||||
"hash": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788",
|
||||
"hash_raw": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788",
|
||||
"size": 184364,
|
||||
@@ -45,7 +45,7 @@
|
||||
},
|
||||
{
|
||||
"name": "devcfg",
|
||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz",
|
||||
"hash": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585",
|
||||
"hash_raw": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585",
|
||||
"size": 40336,
|
||||
@@ -56,7 +56,7 @@
|
||||
},
|
||||
{
|
||||
"name": "boot",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/boot-aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb.img.xz",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/boot-aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb.img.xz",
|
||||
"hash": "aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb",
|
||||
"hash_raw": "aea4aecefd188d9c95726b699902378676c6266a7ae37008b5c2aa0e1e1190fb",
|
||||
"size": 18216960,
|
||||
@@ -67,18 +67,14 @@
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b.img.xz",
|
||||
"hash": "a7bec67c4fef85c66736e74ee8828cbef320f3729f72fee6bea4c97f23dc8b70",
|
||||
"hash_raw": "37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b",
|
||||
"url": "https://gitlvb.teallvbs.xyz/IQ.Lvbs/iqos/raw/branch/master/system-44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa.img.xz",
|
||||
"hash": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"hash_raw": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"size": 6291456000,
|
||||
"sparse": true,
|
||||
"sparse": false,
|
||||
"full_check": false,
|
||||
"has_ab": true,
|
||||
"ondevice_hash": "f678dbc0ffb12e49e6b561ce58d84d3831dc7b7a595909f653b330ecec9c2c65",
|
||||
"alt": {
|
||||
"hash": "37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b",
|
||||
"url": "https://sdn.konn3kt.com/agnos/16-iqlvbs/system-37572981c7592d5dd20136e13bed9a9fae84ffc75b9b24da55704bbce7da239b.img",
|
||||
"size": 6291456000
|
||||
}
|
||||
"ondevice_hash": "44b251e1b3d8cd9243d5c79287d2a0e74b5063d3e21b24192b1293430a3471aa",
|
||||
"url_parts": 10
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1 +1 @@
|
||||
PvU/rNvS8JnrZabBbjgss1lyLIlUGXdEOsguFCMK22aY2p/MlzzzpI2+3Wz7tCNcPT+FEbLR1SrskEjTBvKsCQ==
|
||||
9LDZugtT9q8jFab1Gs8qTmfJukKU8NzDAuT9VakInuOUHCCnN5SDFI/Ew/6C/+3SAlcROgZON/4J8FQyQGV+Dg==
|
||||
|
||||
@@ -3,18 +3,42 @@ import os
|
||||
import requests
|
||||
|
||||
TEST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)))
|
||||
MANIFEST = os.path.join(TEST_DIR, "../agnos.json")
|
||||
MANIFESTS = [
|
||||
os.path.join(TEST_DIR, "../agnos.json"),
|
||||
os.path.join(TEST_DIR, "../agnos_tici_15_1.json"),
|
||||
]
|
||||
|
||||
IMAGE_HOST = "gitlvb.teallvbs.xyz"
|
||||
|
||||
# image payloads are xz streams; the repo raw endpoint would serve an LFS pointer
|
||||
XZ_MAGIC = b"\xfd7zXZ\x00"
|
||||
LFS_POINTER_MAGIC = b"version https://git-lfs"
|
||||
|
||||
|
||||
class TestAgnosUpdater:
|
||||
|
||||
def test_manifest(self):
|
||||
with open(MANIFEST) as f:
|
||||
m = json.load(f)
|
||||
for manifest in MANIFESTS:
|
||||
with open(manifest) as f:
|
||||
m = json.load(f)
|
||||
|
||||
for img in m:
|
||||
r = requests.head(img['url'], timeout=10)
|
||||
r.raise_for_status()
|
||||
assert r.headers['Content-Type'].split(';', 1)[0] in {"application/x-xz", "application/octet-stream"}
|
||||
if not img['sparse']:
|
||||
assert img['hash'] == img['hash_raw']
|
||||
for img in m:
|
||||
assert img['url'].split('/')[2] == IMAGE_HOST
|
||||
if not img['sparse']:
|
||||
assert img['hash'] == img['hash_raw']
|
||||
|
||||
# contract: images are distributed from a private repo, so an anonymous
|
||||
# request must never receive image content. The denial status varies by
|
||||
# route (404 via the CDN, catch-all HTML page when resolved directly to
|
||||
# the origin), so assert on the payload, not the status code. trust_env
|
||||
# off: requests otherwise picks up ~/.netrc (CI runners have gitlvb
|
||||
# credentials), silently authenticating the "anonymous" probe.
|
||||
s = requests.Session()
|
||||
s.trust_env = False
|
||||
r = s.get(img['url'], timeout=10, stream=True,
|
||||
headers={"User-Agent": "IQOS-Updater"})
|
||||
if r.status_code in (401, 403, 404):
|
||||
continue
|
||||
head = next(r.iter_content(chunk_size=256), b"") or b""
|
||||
assert not head.startswith(XZ_MAGIC), f"{img['name']}: anonymous request served image content"
|
||||
assert not head.startswith(LFS_POINTER_MAGIC), f"{img['name']}: anonymous request served the LFS pointer"
|
||||
|
||||
Reference in New Issue
Block a user