intermediate commit
This commit is contained in:
44
tools/release/govoplan_release/http_fetch.py
Normal file
44
tools/release/govoplan_release/http_fetch.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""Validated HTTP helpers for release tooling."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from dataclasses import dataclass
|
||||
from typing import Mapping
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class HttpFetchResponse:
|
||||
status: int
|
||||
headers: dict[str, str]
|
||||
body: bytes
|
||||
|
||||
def text(self, encoding: str = "utf-8") -> str:
|
||||
return self.body.decode(encoding)
|
||||
|
||||
|
||||
def validate_http_url(value: str, *, label: str = "URL") -> str:
|
||||
parsed = urllib.parse.urlparse(str(value).strip())
|
||||
if parsed.scheme not in {"http", "https"} or not parsed.netloc:
|
||||
raise ValueError(f"{label} must be an absolute HTTP(S) URL.")
|
||||
if parsed.username or parsed.password:
|
||||
raise ValueError(f"{label} must not include embedded credentials.")
|
||||
return urllib.parse.urlunparse(parsed)
|
||||
|
||||
|
||||
def fetch_http(
|
||||
url: str,
|
||||
*,
|
||||
timeout: float,
|
||||
label: str = "URL",
|
||||
method: str = "GET",
|
||||
headers: Mapping[str, str] | None = None,
|
||||
) -> HttpFetchResponse:
|
||||
request = urllib.request.Request(validate_http_url(url, label=label), headers=dict(headers or {}), method=method)
|
||||
with urllib.request.urlopen(request, timeout=timeout) as response: # noqa: S310 - URL is validated by validate_http_url. # nosec B310 # nosemgrep: python.lang.security.audit.dynamic-urllib-use-detected.dynamic-urllib-use-detected
|
||||
return HttpFetchResponse(
|
||||
status=int(getattr(response, "status", 0)),
|
||||
headers=dict(response.headers.items()),
|
||||
body=response.read(),
|
||||
)
|
||||
Reference in New Issue
Block a user