Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03aa3efc8e |
@ -1 +0,0 @@
|
|||||||
1
|
|
||||||
59
.gitignore
vendored
59
.gitignore
vendored
@ -1,57 +1,2 @@
|
|||||||
/urllib3-1.5.tar.gz
|
SOURCES/hypercorn-d1719f8c1570cbd8e6a3719ffdb14a4d72880abb.tar.gz
|
||||||
/urllib3-1.7.tar.gz
|
SOURCES/urllib3-2.6.3.tar.gz
|
||||||
/urllib3-1.7.1.tar.gz
|
|
||||||
/urllib3-1.8.2.tar.gz
|
|
||||||
/urllib3-1.9.1.tar.gz
|
|
||||||
/urllib3-1.10.tar.gz
|
|
||||||
/urllib3-1.10.1.tar.gz
|
|
||||||
/urllib3-1.10.2.tar.gz
|
|
||||||
/urllib3-1.10.3.tar.gz
|
|
||||||
/urllib3-585983ab3f7fb7a0e0b223ebdab1b45471dbefe4.tar.gz
|
|
||||||
/urllib3-a91975b77a2e28394859487fe5ebbf4a3a74e634.tar.gz
|
|
||||||
/urllib3-1.10.4.tar.gz
|
|
||||||
/urllib3-1.12.tar.gz
|
|
||||||
/urllib3-1.13.tar.gz
|
|
||||||
/urllib3-1.13.1.tar.gz
|
|
||||||
/urllib3-1.15.1.tar.gz
|
|
||||||
/urllib3-1.16.tar.gz
|
|
||||||
/urllib3-1.19.1.tar.gz
|
|
||||||
/urllib3-1.20.tar.gz
|
|
||||||
/urllib3-1.21.1.tar.gz
|
|
||||||
/urllib3-1.22.tar.gz
|
|
||||||
/urllib3-1.23.tar.gz
|
|
||||||
/urllib3-1.24.tar.gz
|
|
||||||
/urllib3-1.24.1.tar.gz
|
|
||||||
/urllib3-1.24.2.tar.gz
|
|
||||||
/urllib3-1.25.2.tar.gz
|
|
||||||
/urllib3-1.25.3.tar.gz
|
|
||||||
/urllib3-1.25.6.tar.gz
|
|
||||||
/urllib3-1.25.7.tar.gz
|
|
||||||
/urllib3-1.25.8.tar.gz
|
|
||||||
/urllib3-1.25.10.tar.gz
|
|
||||||
/urllib3-1.26.4.tar.gz
|
|
||||||
/urllib3-1.26.5.tar.gz
|
|
||||||
/urllib3-1.26.6.tar.gz
|
|
||||||
/urllib3-1.26.7.tar.gz
|
|
||||||
/urllib3-1.26.8.tar.gz
|
|
||||||
/urllib3-1.26.9.tar.gz
|
|
||||||
/urllib3-1.26.12.tar.gz
|
|
||||||
/urllib3-1.26.15.tar.gz
|
|
||||||
/urllib3-1.26.16.tar.gz
|
|
||||||
/urllib3-1.26.17.tar.gz
|
|
||||||
/urllib3-1.26.18.tar.gz
|
|
||||||
/urllib3-1.26.19.tar.gz
|
|
||||||
/urllib3-2.0.7.tar.gz
|
|
||||||
/urllib3-2.1.0.tar.gz
|
|
||||||
/urllib3-2.2.0.tar.gz
|
|
||||||
/hypercorn-d1719f8c1570cbd8e6a3719ffdb14a4d72880abb.tar.gz
|
|
||||||
/urllib3-2.2.1.tar.gz
|
|
||||||
/urllib3-2.2.2.tar.gz
|
|
||||||
/urllib3-2.2.3.tar.gz
|
|
||||||
/urllib3-2.3.0.tar.gz
|
|
||||||
/urllib3-2.4.0.tar.gz
|
|
||||||
/urllib3-2.5.0.tar.gz
|
|
||||||
/urllib3-2.6.0.tar.gz
|
|
||||||
/urllib3-2.6.1.tar.gz
|
|
||||||
/urllib3-2.6.2.tar.gz
|
|
||||||
/urllib3-2.6.3.tar.gz
|
|
||||||
|
|||||||
2
.python3.14-urllib3.metadata
Normal file
2
.python3.14-urllib3.metadata
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
ef705aa48f54fe121d3094494e8673173e983453 SOURCES/hypercorn-d1719f8c1570cbd8e6a3719ffdb14a4d72880abb.tar.gz
|
||||||
|
21d815e6e5244c8c6ec1493a7765ec9900b9d558 SOURCES/urllib3-2.6.3.tar.gz
|
||||||
@ -1,158 +0,0 @@
|
|||||||
From 5ec0de499b9166ca71c65ab04f2a7e4eb0d66fcc Mon Sep 17 00:00:00 2001
|
|
||||||
From: Illia Volochii <illia.volochii@gmail.com>
|
|
||||||
Date: Thu, 7 May 2026 18:40:31 +0300
|
|
||||||
Subject: [PATCH] Merge commit from fork
|
|
||||||
|
|
||||||
* Remove sensitive headers in proxy pools too
|
|
||||||
|
|
||||||
* Add a changelog entry
|
|
||||||
|
|
||||||
* Check retries history in tests
|
|
||||||
|
|
||||||
Co-authored-by: Copilot <copilot@github.com>
|
|
||||||
|
|
||||||
---------
|
|
||||||
|
|
||||||
Co-authored-by: Copilot <copilot@github.com>
|
|
||||||
---
|
|
||||||
changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst | 3 +
|
|
||||||
dummyserver/asgi_proxy.py | 1 +
|
|
||||||
src/urllib3/connectionpool.py | 12 ++++
|
|
||||||
.../test_proxy_poolmanager.py | 72 +++++++++++++++++++
|
|
||||||
4 files changed, 88 insertions(+)
|
|
||||||
create mode 100644 changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
|
|
||||||
|
|
||||||
diff --git a/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst b/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..bac765ea28
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/changelog/GHSA-qccp-gfcp-xxvc.bugfix.rst
|
|
||||||
@@ -0,0 +1,3 @@
|
|
||||||
+Fixed HTTP pools created using ``ProxyManager.connection_from_url`` to strip
|
|
||||||
+sensitive headers specified in ``Retry.remove_headers_on_redirect`` when
|
|
||||||
+redirecting to a different host.
|
|
||||||
diff --git a/dummyserver/asgi_proxy.py b/dummyserver/asgi_proxy.py
|
|
||||||
index 00c0a1b8b8..3ff1867380 100755
|
|
||||||
--- a/dummyserver/asgi_proxy.py
|
|
||||||
+++ b/dummyserver/asgi_proxy.py
|
|
||||||
@@ -56,6 +56,7 @@ async def absolute_uri(
|
|
||||||
client_response = await client.request(
|
|
||||||
method=scope["method"],
|
|
||||||
url=scope["path"],
|
|
||||||
+ params=scope["query_string"].decode(),
|
|
||||||
headers=list(scope["headers"]),
|
|
||||||
content=await _read_body(receive),
|
|
||||||
)
|
|
||||||
diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py
|
|
||||||
index 9b66218bf1..70fbc5e725 100644
|
|
||||||
--- a/src/urllib3/connectionpool.py
|
|
||||||
+++ b/src/urllib3/connectionpool.py
|
|
||||||
@@ -897,6 +897,18 @@ def urlopen( # type: ignore[override]
|
|
||||||
body = None
|
|
||||||
headers = HTTPHeaderDict(headers)._prepare_for_method_change()
|
|
||||||
|
|
||||||
+ # Strip headers marked as unsafe to forward to the redirected location.
|
|
||||||
+ # Check remove_headers_on_redirect to avoid a potential network call within
|
|
||||||
+ # self.is_same_host() which may use socket.gethostbyname() in the future.
|
|
||||||
+ if retries.remove_headers_on_redirect and not self.is_same_host(
|
|
||||||
+ redirect_location
|
|
||||||
+ ):
|
|
||||||
+ new_headers = headers.copy() # type: ignore[union-attr]
|
|
||||||
+ for header in headers:
|
|
||||||
+ if header.lower() in retries.remove_headers_on_redirect:
|
|
||||||
+ new_headers.pop(header, None)
|
|
||||||
+ headers = new_headers
|
|
||||||
+
|
|
||||||
try:
|
|
||||||
retries = retries.increment(method, url, response=response, _pool=self)
|
|
||||||
except MaxRetryError:
|
|
||||||
diff --git a/test/with_dummyserver/test_proxy_poolmanager.py b/test/with_dummyserver/test_proxy_poolmanager.py
|
|
||||||
index 4a932c0de4..6921bc6d22 100644
|
|
||||||
--- a/test/with_dummyserver/test_proxy_poolmanager.py
|
|
||||||
+++ b/test/with_dummyserver/test_proxy_poolmanager.py
|
|
||||||
@@ -37,6 +37,7 @@
|
|
||||||
SSLError,
|
|
||||||
)
|
|
||||||
from urllib3.poolmanager import ProxyManager, proxy_from_url
|
|
||||||
+from urllib3.util.retry import RequestHistory
|
|
||||||
from urllib3.util.ssl_ import create_urllib3_context
|
|
||||||
from urllib3.util.timeout import Timeout
|
|
||||||
|
|
||||||
@@ -300,6 +301,77 @@ def test_cross_host_redirect(self) -> None:
|
|
||||||
assert r._pool is not None
|
|
||||||
assert r._pool.host != self.http_host_alt
|
|
||||||
|
|
||||||
+ _sensitive_headers = {
|
|
||||||
+ "Authorization": "foo",
|
|
||||||
+ "Proxy-Authorization": "bar",
|
|
||||||
+ "Cookie": "foo=bar",
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @pytest.mark.parametrize(
|
|
||||||
+ "sensitive_headers",
|
|
||||||
+ (_sensitive_headers, {k.lower(): v for k, v in _sensitive_headers.items()}),
|
|
||||||
+ ids=("capitalized", "lowercase"),
|
|
||||||
+ )
|
|
||||||
+ def test_cross_host_redirect_remove_headers_via_proxy_manager(
|
|
||||||
+ self, sensitive_headers: dict[str, str]
|
|
||||||
+ ) -> None:
|
|
||||||
+ headers_url = f"{self.http_url_alt}/headers"
|
|
||||||
+ initial_url = f"{self.http_url}/redirect?target={headers_url}"
|
|
||||||
+ with proxy_from_url(self.proxy_url) as proxy_mgr:
|
|
||||||
+ r = proxy_mgr.request(
|
|
||||||
+ "GET", initial_url, headers=sensitive_headers, retries=1
|
|
||||||
+ )
|
|
||||||
+ assert r.status == 200
|
|
||||||
+ assert r.retries is not None
|
|
||||||
+ assert r.retries.history == (
|
|
||||||
+ RequestHistory(
|
|
||||||
+ method="GET",
|
|
||||||
+ url=initial_url,
|
|
||||||
+ error=None,
|
|
||||||
+ status=303,
|
|
||||||
+ redirect_location=headers_url,
|
|
||||||
+ ),
|
|
||||||
+ )
|
|
||||||
+ data = r.json()
|
|
||||||
+ for header in sensitive_headers:
|
|
||||||
+ assert header not in data
|
|
||||||
+
|
|
||||||
+ @pytest.mark.parametrize(
|
|
||||||
+ "sensitive_headers",
|
|
||||||
+ (_sensitive_headers, {k.lower(): v for k, v in _sensitive_headers.items()}),
|
|
||||||
+ ids=("capitalized", "lowercase"),
|
|
||||||
+ )
|
|
||||||
+ def test_cross_host_redirect_remove_headers_via_pool(
|
|
||||||
+ self, sensitive_headers: dict[str, str]
|
|
||||||
+ ) -> None:
|
|
||||||
+ headers_url = f"{self.http_url_alt}/headers"
|
|
||||||
+ initial_url = f"{self.http_url}/redirect?target={headers_url}"
|
|
||||||
+ with proxy_from_url(self.proxy_url) as proxy_mgr:
|
|
||||||
+ pool = proxy_mgr.connection_from_url(self.http_url)
|
|
||||||
+ r = pool.urlopen(
|
|
||||||
+ "GET",
|
|
||||||
+ initial_url,
|
|
||||||
+ headers=sensitive_headers,
|
|
||||||
+ retries=1,
|
|
||||||
+ redirect=True,
|
|
||||||
+ assert_same_host=False,
|
|
||||||
+ preload_content=True,
|
|
||||||
+ )
|
|
||||||
+ assert r.status == 200
|
|
||||||
+ assert r.retries is not None
|
|
||||||
+ assert r.retries.history == (
|
|
||||||
+ RequestHistory(
|
|
||||||
+ method="GET",
|
|
||||||
+ url=initial_url,
|
|
||||||
+ error=None,
|
|
||||||
+ status=303,
|
|
||||||
+ redirect_location=headers_url,
|
|
||||||
+ ),
|
|
||||||
+ )
|
|
||||||
+ data = r.json()
|
|
||||||
+ for header in sensitive_headers:
|
|
||||||
+ assert header not in data
|
|
||||||
+
|
|
||||||
def test_cross_protocol_redirect(self) -> None:
|
|
||||||
with proxy_from_url(self.proxy_url, ca_certs=DEFAULT_CA) as http:
|
|
||||||
cross_protocol_location = f"{self.https_url}/echo?a=b"
|
|
||||||
@ -1,162 +0,0 @@
|
|||||||
From 2bdcc44d1e163fb5cc48a8662425e35e15adfe6a Mon Sep 17 00:00:00 2001
|
|
||||||
From: Illia Volochii <illia.volochii@gmail.com>
|
|
||||||
Date: Thu, 7 May 2026 18:39:03 +0300
|
|
||||||
Subject: [PATCH] Merge commit from fork
|
|
||||||
|
|
||||||
* Avoid any decoding in `HTTPResponse.drain_conn`
|
|
||||||
|
|
||||||
* Add a comment
|
|
||||||
|
|
||||||
* Simplify `drain_conn`
|
|
||||||
|
|
||||||
* Add tests
|
|
||||||
|
|
||||||
* Add additional checks to the test
|
|
||||||
|
|
||||||
* Fix full decompression on the 2nd small read from response using Brotli
|
|
||||||
|
|
||||||
* Add a changelog entry
|
|
||||||
|
|
||||||
* Inverse the order in the changelog entry
|
|
||||||
|
|
||||||
* Mention `stream` call
|
|
||||||
---
|
|
||||||
changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst | 7 +++++++
|
|
||||||
src/urllib3/response.py | 17 +++++++++++------
|
|
||||||
test/test_response.py | 24 +++++++++++++++++++++---
|
|
||||||
test/with_dummyserver/test_connection.py | 19 +++++++++++++++++++
|
|
||||||
4 files changed, 58 insertions(+), 9 deletions(-)
|
|
||||||
create mode 100644 changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst
|
|
||||||
|
|
||||||
diff --git a/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst b/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000000..ac70af825a
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/changelog/GHSA-mf9v-mfxr-j63j.bugfix.rst
|
|
||||||
@@ -0,0 +1,7 @@
|
|
||||||
+Fixed two high-severity security issues where decompression-bomb safeguards of the streaming API were bypassed:
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+1. When ``HTTPResponse.drain_conn()`` was called after the response had been read and decompressed partially.
|
|
||||||
+2. During the second ``HTTPResponse.read(amt=N)`` or ``HTTPResponse.stream(amt=N)`` call when the response was decompressed using the official `Brotli <https://pypi.org/project/brotli/>`__ library.
|
|
||||||
+
|
|
||||||
+See `GHSA-mf9v-mfxr-j63j <https://github.com/urllib3/urllib3/security/advisories/GHSA-mf9v-mfxr-j63j>`__ for details.
|
|
||||||
diff --git a/src/urllib3/response.py b/src/urllib3/response.py
|
|
||||||
index 521c31b282..e9246b75e3 100644
|
|
||||||
--- a/src/urllib3/response.py
|
|
||||||
+++ b/src/urllib3/response.py
|
|
||||||
@@ -798,13 +798,14 @@ def drain_conn(self) -> None:
|
|
||||||
Unread data in the HTTPResponse connection blocks the connection from being released back to the pool.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
- self.read(
|
|
||||||
- # Do not spend resources decoding the content unless
|
|
||||||
- # decoding has already been initiated.
|
|
||||||
- decode_content=self._has_decoded_content,
|
|
||||||
- )
|
|
||||||
+ self._raw_read()
|
|
||||||
except (HTTPError, OSError, BaseSSLError, HTTPException):
|
|
||||||
pass
|
|
||||||
+ if self._has_decoded_content:
|
|
||||||
+ # `_raw_read` skips decompression, so we should clean up the
|
|
||||||
+ # decoder to avoid keeping unnecessary data in memory.
|
|
||||||
+ self._decoded_buffer = BytesQueueBuffer()
|
|
||||||
+ self._decoder = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def data(self) -> bytes:
|
|
||||||
@@ -1091,7 +1092,11 @@ def read(
|
|
||||||
elif amt is not None:
|
|
||||||
cache_content = False
|
|
||||||
|
|
||||||
- if self._decoder and self._decoder.has_unconsumed_tail:
|
|
||||||
+ if (
|
|
||||||
+ self._decoder
|
|
||||||
+ and self._decoder.has_unconsumed_tail
|
|
||||||
+ and len(self._decoded_buffer) < amt
|
|
||||||
+ ):
|
|
||||||
decoded_data = self._decode(
|
|
||||||
b"",
|
|
||||||
decode_content,
|
|
||||||
diff --git a/test/test_response.py b/test/test_response.py
|
|
||||||
index c70262c04e..da521137bf 100644
|
|
||||||
--- a/test/test_response.py
|
|
||||||
+++ b/test/test_response.py
|
|
||||||
@@ -858,22 +858,33 @@ def test_memory_usage_decode_with_max_length(
|
|
||||||
pytest.skip(f"Proper {request.node.callspec.id} decoder is not available")
|
|
||||||
|
|
||||||
name, compressed_data = data
|
|
||||||
- limit = 1024 * 1024 # 1 MiB
|
|
||||||
+ limit1 = 1024 * 1024 # 1 MiB
|
|
||||||
+ # We test with two read calls because the second call may be
|
|
||||||
+ # able to use the internal buffer filled by the first call, and
|
|
||||||
+ # we want to ensure that full decompression is never triggered
|
|
||||||
+ # by the second call. The limit for the second call is lowered
|
|
||||||
+ # to make sure that the internal buffer is used for the Brotli
|
|
||||||
+ # case specifically https://github.com/google/brotli/issues/1396
|
|
||||||
+ limit2 = 1024 # 1 KiB
|
|
||||||
if read_method in ("read_chunked", "stream"):
|
|
||||||
httplib_r = httplib.HTTPResponse(MockSock) # type: ignore[arg-type]
|
|
||||||
+ httplib_r.chunked = True
|
|
||||||
+ httplib_r.chunk_left = 1
|
|
||||||
httplib_r.fp = MockChunkedEncodingResponse([compressed_data]) # type: ignore[assignment]
|
|
||||||
r = HTTPResponse(
|
|
||||||
httplib_r,
|
|
||||||
preload_content=False,
|
|
||||||
headers={"transfer-encoding": "chunked", "content-encoding": name},
|
|
||||||
)
|
|
||||||
- next(getattr(r, read_method)(amt=limit, decode_content=True))
|
|
||||||
+ for limit in (limit1, limit2):
|
|
||||||
+ next(getattr(r, read_method)(amt=limit, decode_content=True))
|
|
||||||
else:
|
|
||||||
fp = BytesIO(compressed_data)
|
|
||||||
r = HTTPResponse(
|
|
||||||
fp, headers={"content-encoding": name}, preload_content=False
|
|
||||||
)
|
|
||||||
- getattr(r, read_method)(amt=limit, decode_content=True)
|
|
||||||
+ for limit in (limit1, limit2):
|
|
||||||
+ getattr(r, read_method)(amt=limit, decode_content=True)
|
|
||||||
|
|
||||||
# Check that the internal decoded buffer is empty unless brotli
|
|
||||||
# is used.
|
|
||||||
@@ -883,6 +894,13 @@ def test_memory_usage_decode_with_max_length(
|
|
||||||
if name != "br" or brotli.__name__ == "brotlicffi":
|
|
||||||
assert len(r._decoded_buffer) == 0
|
|
||||||
|
|
||||||
+ # Check that memory usage is still within the limit while the
|
|
||||||
+ # connection is being drained, meaning that the call does not
|
|
||||||
+ # decompress the whole content.
|
|
||||||
+ r.drain_conn()
|
|
||||||
+ assert r._decoder is None
|
|
||||||
+ assert len(r._decoded_buffer) == 0
|
|
||||||
+
|
|
||||||
def test_multi_decoding_deflate_deflate(self) -> None:
|
|
||||||
data = zlib.compress(zlib.compress(b"foo"))
|
|
||||||
|
|
||||||
diff --git a/test/with_dummyserver/test_connection.py b/test/with_dummyserver/test_connection.py
|
|
||||||
index b9c547c00f..940815dac2 100644
|
|
||||||
--- a/test/with_dummyserver/test_connection.py
|
|
||||||
+++ b/test/with_dummyserver/test_connection.py
|
|
||||||
@@ -138,3 +138,22 @@ def test_invalid_tunnel_scheme(pool: HTTPConnectionPool) -> None:
|
|
||||||
str(e.value)
|
|
||||||
== "Invalid proxy scheme for tunneling: 'socks', must be either 'http' or 'https'"
|
|
||||||
)
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+def test_response_after_drain_conn(pool: HTTPConnectionPool) -> None:
|
|
||||||
+ """
|
|
||||||
+ Test that a connection can be reused after calling `drain_conn` on
|
|
||||||
+ an unread response.
|
|
||||||
+ """
|
|
||||||
+ conn = pool._get_conn()
|
|
||||||
+
|
|
||||||
+ conn.request("GET", "/", preload_content=False)
|
|
||||||
+ response = conn.getresponse()
|
|
||||||
+ assert response.status == 200
|
|
||||||
+ response.drain_conn()
|
|
||||||
+
|
|
||||||
+ conn.request("GET", "/", preload_content=False)
|
|
||||||
+ response = conn.getresponse()
|
|
||||||
+ assert response.status == 200
|
|
||||||
+
|
|
||||||
+ conn.close()
|
|
||||||
@ -1,3 +1,13 @@
|
|||||||
|
## START: Set by rpmautospec
|
||||||
|
## (rpmautospec version 0.6.5)
|
||||||
|
## RPMAUTOSPEC: autorelease, autochangelog
|
||||||
|
%define autorelease(e:s:pb:n) %{?-p:0.}%{lua:
|
||||||
|
release_number = 1;
|
||||||
|
base_release_number = tonumber(rpm.expand("%{?-b*}%{!?-b:1}"));
|
||||||
|
print(release_number + base_release_number - 1);
|
||||||
|
}%{?-e:.%{-e*}}%{?-s:.%{-s*}}%{!?-n:%{?dist}}
|
||||||
|
## END: Set by rpmautospec
|
||||||
|
|
||||||
%global python3_pkgversion 3.14
|
%global python3_pkgversion 3.14
|
||||||
|
|
||||||
# When bootstrapping Python, we cannot test this yet
|
# When bootstrapping Python, we cannot test this yet
|
||||||
@ -37,9 +47,6 @@ Patch: Replace-hatchling-with-setuptools-build-backend.patch
|
|||||||
%global hypercorn_commit d1719f8c1570cbd8e6a3719ffdb14a4d72880abb
|
%global hypercorn_commit d1719f8c1570cbd8e6a3719ffdb14a4d72880abb
|
||||||
Source1: %{hypercorn_url}/archive/%{hypercorn_commit}/hypercorn-%{hypercorn_commit}.tar.gz
|
Source1: %{hypercorn_url}/archive/%{hypercorn_commit}/hypercorn-%{hypercorn_commit}.tar.gz
|
||||||
|
|
||||||
Patch: CVE-2026-44431.patch
|
|
||||||
Patch: CVE-2026-44432.patch
|
|
||||||
|
|
||||||
BuildArch: noarch
|
BuildArch: noarch
|
||||||
|
|
||||||
BuildRequires: python%{python3_pkgversion}-devel
|
BuildRequires: python%{python3_pkgversion}-devel
|
||||||
@ -82,7 +89,7 @@ many critical features that are missing from the Python standard libraries:
|
|||||||
|
|
||||||
|
|
||||||
%prep
|
%prep
|
||||||
%autosetup -p1 -n urllib3-%{version}
|
%autosetup -n urllib3-%{version}
|
||||||
%setup -q -n urllib3-%{version} -T -D -b 1
|
%setup -q -n urllib3-%{version} -T -D -b 1
|
||||||
|
|
||||||
# Make sure that the RECENT_DATE value doesn't get too far behind what the current date is.
|
# Make sure that the RECENT_DATE value doesn't get too far behind what the current date is.
|
||||||
@ -185,4 +192,25 @@ k="${k-}${k+ and }not (TestHTTPProxyManager and test_tunneling_proxy_request_tim
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
%autochangelog
|
## START: Generated by rpmautospec
|
||||||
|
* Tue Jan 27 2026 Benjamin A. Beasley <code@musicinmybrain.net> - 2.6.3-1
|
||||||
|
- Update to 2.6.3
|
||||||
|
- Fixes CVE-2026-21441 / GHSA-38jv-5279-wg99
|
||||||
|
|
||||||
|
* Tue Jan 27 2026 Benjamin A. Beasley <code@musicinmybrain.net> - 2.6.2-1
|
||||||
|
- Update to 2.6.2
|
||||||
|
|
||||||
|
* Tue Jan 27 2026 Benjamin A. Beasley <code@musicinmybrain.net> - 2.6.1-1
|
||||||
|
- Update to 2.6.1
|
||||||
|
- Fixes CVE-2025-66471 / GHSA-2xpw-w6gg-jr37
|
||||||
|
- Fixes CVE-2025-66418 / GHSA-gm62-xv2j-4w53
|
||||||
|
|
||||||
|
* Fri Nov 28 2025 Lukáš Zachar <lzachar@redhat.com> - 2.5.0-3
|
||||||
|
- Add gating
|
||||||
|
|
||||||
|
* Fri Nov 28 2025 Tomáš Hrnčiar <thrnciar@redhat.com> - 2.5.0-2
|
||||||
|
- Convert from Fedora for the Python 3.14 stack in RHEL
|
||||||
|
|
||||||
|
* Fri Nov 28 2025 Tomáš Hrnčiar <thrnciar@redhat.com> - 2.5.0-1
|
||||||
|
- RHEL: Rename SPEC to python3.14-urllib3.spec
|
||||||
|
## END: Generated by rpmautospec
|
||||||
@ -1,6 +0,0 @@
|
|||||||
--- !Policy
|
|
||||||
product_versions:
|
|
||||||
- rhel-*
|
|
||||||
decision_context: osci_compose_gate
|
|
||||||
rules:
|
|
||||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
|
||||||
@ -1 +0,0 @@
|
|||||||
addFilter(r"spelling-error \('(gzip|brotli|zstd)',")
|
|
||||||
2
sources
2
sources
@ -1,2 +0,0 @@
|
|||||||
SHA512 (urllib3-2.6.3.tar.gz) = 554cedfd97d411fffa9a8ba46f592eab9e58c5fa8822ecd5a73ab45d6adfc188a6b9c4e238d02a4fbd3a1067a25a1de841a33d398d0641e22a32ea414876b615
|
|
||||||
SHA512 (hypercorn-d1719f8c1570cbd8e6a3719ffdb14a4d72880abb.tar.gz) = 62d6787d88a2e716f0ac04fc49f6cdc586e473a660ee754ff66961922ae78bcc75d1f78b091e78557dd60f006e8e480114738c7b4ff71beac804e4fc9603240b
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
test: python3.14 test.py
|
|
||||||
framework: shell
|
|
||||||
require:
|
|
||||||
- python3.14
|
|
||||||
- python3.14-urllib3
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import urllib3
|
|
||||||
|
|
||||||
http = urllib3.PoolManager()
|
|
||||||
r = http.request('GET', 'http://example.com/')
|
|
||||||
print('status = {0}'.format(r.status))
|
|
||||||
print(r.data)
|
|
||||||
if r.status != 200 or not r.data:
|
|
||||||
raise SystemExit(1)
|
|
||||||
Loading…
Reference in New Issue
Block a user