[rh:urllib] Do not read after close (#15049)

Fix regression introduced in 5767fb4ab1

Closes #15017
Authored by: bashonly
pull/13187/merge
bashonly 2 weeks ago committed by GitHub
parent 23f1ab3469
commit 6ee6a6fc58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -755,6 +755,17 @@ class TestHTTPRequestHandler(TestRequestHandlerBase):
assert res.read(0) == b'' assert res.read(0) == b''
assert res.read() == b'<video src="/vid.mp4" /></html>' assert res.read() == b'<video src="/vid.mp4" /></html>'
def test_partial_read_greater_than_response_then_full_read(self, handler):
with handler() as rh:
for encoding in ('', 'gzip', 'deflate'):
res = validate_and_send(rh, Request(
f'http://127.0.0.1:{self.http_port}/content-encoding',
headers={'ytdl-encoding': encoding}))
assert res.headers.get('Content-Encoding') == encoding
assert res.read(512) == b'<html><video src="/vid.mp4" /></html>'
assert res.read(0) == b''
assert res.read() == b''
@pytest.mark.parametrize('handler', ['Urllib', 'Requests', 'CurlCFFI'], indirect=True) @pytest.mark.parametrize('handler', ['Urllib', 'Requests', 'CurlCFFI'], indirect=True)
@pytest.mark.handler_flaky('CurlCFFI', reason='segfaults') @pytest.mark.handler_flaky('CurlCFFI', reason='segfaults')
@ -920,6 +931,28 @@ class TestUrllibRequestHandler(TestRequestHandlerBase):
assert res.fp.fp is None assert res.fp.fp is None
assert res.closed assert res.closed
def test_data_uri_partial_read_then_full_read(self, handler):
with handler() as rh:
res = validate_and_send(rh, Request('data:text/plain,hello%20world'))
assert res.read(6) == b'hello '
assert res.read(0) == b''
assert res.read() == b'world'
# Should automatically close the underlying file object
assert res.fp.closed
assert res.closed
def test_data_uri_partial_read_greater_than_response_then_full_read(self, handler):
with handler() as rh:
res = validate_and_send(rh, Request('data:text/plain,hello%20world'))
assert res.read(512) == b'hello world'
# Response and its underlying file object should already be closed now
assert res.fp.closed
assert res.closed
assert res.read(0) == b''
assert res.read() == b''
assert res.fp.closed
assert res.closed
def test_http_error_returns_content(self, handler): def test_http_error_returns_content(self, handler):
# urllib HTTPError will try close the underlying response if reference to the HTTPError object is lost # urllib HTTPError will try close the underlying response if reference to the HTTPError object is lost
def get_response(): def get_response():

@ -40,7 +40,7 @@ TEST_DIR = os.path.dirname(os.path.abspath(__file__))
pytestmark = pytest.mark.handler_flaky( pytestmark = pytest.mark.handler_flaky(
'Websockets', 'Websockets',
os.name != 'nt' and sys.implementation.name == 'pypy', os.name == 'nt' or sys.implementation.name == 'pypy',
reason='segfaults', reason='segfaults',
) )

@ -305,6 +305,8 @@ class UrllibResponseAdapter(Response):
status=getattr(res, 'status', None) or res.getcode(), reason=getattr(res, 'reason', None)) status=getattr(res, 'status', None) or res.getcode(), reason=getattr(res, 'reason', None))
def read(self, amt=None): def read(self, amt=None):
if self.closed:
return b''
try: try:
data = self.fp.read(amt) data = self.fp.read(amt)
underlying = getattr(self.fp, 'fp', None) underlying = getattr(self.fp, 'fp', None)

Loading…
Cancel
Save