Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
ce911c3f
Commit
ce911c3f
authored
Mar 17, 2016
by
Martin Panter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #26499: Fixes to HTTPResponse.readline() and read1(), by Silent Ghost
parent
9528334e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
86 additions
and
9 deletions
+86
-9
Doc/library/http.client.rst
Doc/library/http.client.rst
+4
-0
Lib/http/client.py
Lib/http/client.py
+8
-0
Lib/test/test_httplib.py
Lib/test/test_httplib.py
+70
-9
Misc/NEWS
Misc/NEWS
+4
-0
No files found.
Doc/library/http.client.rst
View file @
ce911c3f
...
@@ -362,6 +362,10 @@ server. It provides access to the request headers and the entity
...
@@ -362,6 +362,10 @@ server. It provides access to the request headers and the entity
body. The response is an iterable object and can be used in a with
body. The response is an iterable object and can be used in a with
statement.
statement.
.. versionchanged:: 3.5
The :class:`io.BufferedIOBase` interface is now implemented and
all of its reader operations are supported.
.. method:: HTTPResponse.read([amt])
.. method:: HTTPResponse.read([amt])
...
...
Lib/http/client.py
View file @
ce911c3f
...
@@ -635,6 +635,8 @@ class HTTPResponse(io.BufferedIOBase):
...
@@ -635,6 +635,8 @@ class HTTPResponse(io.BufferedIOBase):
return
b""
return
b""
if
self
.
chunked
:
if
self
.
chunked
:
return
self
.
_read1_chunked
(
n
)
return
self
.
_read1_chunked
(
n
)
if
self
.
length
is
not
None
and
(
n
<
0
or
n
>
self
.
length
):
n
=
self
.
length
try
:
try
:
result
=
self
.
fp
.
read1
(
n
)
result
=
self
.
fp
.
read1
(
n
)
except
ValueError
:
except
ValueError
:
...
@@ -645,6 +647,8 @@ class HTTPResponse(io.BufferedIOBase):
...
@@ -645,6 +647,8 @@ class HTTPResponse(io.BufferedIOBase):
result
=
self
.
fp
.
read1
(
16
*
1024
)
result
=
self
.
fp
.
read1
(
16
*
1024
)
if
not
result
and
n
:
if
not
result
and
n
:
self
.
_close_conn
()
self
.
_close_conn
()
elif
self
.
length
is
not
None
:
self
.
length
-=
len
(
result
)
return
result
return
result
def
peek
(
self
,
n
=-
1
):
def
peek
(
self
,
n
=-
1
):
...
@@ -662,9 +666,13 @@ class HTTPResponse(io.BufferedIOBase):
...
@@ -662,9 +666,13 @@ class HTTPResponse(io.BufferedIOBase):
if
self
.
chunked
:
if
self
.
chunked
:
# Fallback to IOBase readline which uses peek() and read()
# Fallback to IOBase readline which uses peek() and read()
return
super
().
readline
(
limit
)
return
super
().
readline
(
limit
)
if
self
.
length
is
not
None
and
(
limit
<
0
or
limit
>
self
.
length
):
limit
=
self
.
length
result
=
self
.
fp
.
readline
(
limit
)
result
=
self
.
fp
.
readline
(
limit
)
if
not
result
and
limit
:
if
not
result
and
limit
:
self
.
_close_conn
()
self
.
_close_conn
()
elif
self
.
length
is
not
None
:
self
.
length
-=
len
(
result
)
return
result
return
result
def
_read1_chunked
(
self
,
n
):
def
_read1_chunked
(
self
,
n
):
...
...
Lib/test/test_httplib.py
View file @
ce911c3f
...
@@ -341,8 +341,8 @@ class BasicTest(TestCase):
...
@@ -341,8 +341,8 @@ class BasicTest(TestCase):
self
.
assertEqual
(
repr
(
exc
),
'''BadStatusLine("
\
'
\
'
",)'''
)
self
.
assertEqual
(
repr
(
exc
),
'''BadStatusLine("
\
'
\
'
",)'''
)
def
test_partial_reads
(
self
):
def
test_partial_reads
(
self
):
# if we have
a length, the system knows when to close itself
# if we have
Content-Length, HTTPResponse knows when to close itself,
#
same behaviour than
when we read the whole thing with read()
#
the same behaviour as
when we read the whole thing with read()
body
=
"HTTP/1.1 200 Ok
\
r
\
n
Content-Length: 4
\
r
\
n
\
r
\
n
Text"
body
=
"HTTP/1.1 200 Ok
\
r
\
n
Content-Length: 4
\
r
\
n
\
r
\
n
Text"
sock
=
FakeSocket
(
body
)
sock
=
FakeSocket
(
body
)
resp
=
client
.
HTTPResponse
(
sock
)
resp
=
client
.
HTTPResponse
(
sock
)
...
@@ -355,9 +355,24 @@ class BasicTest(TestCase):
...
@@ -355,9 +355,24 @@ class BasicTest(TestCase):
resp
.
close
()
resp
.
close
()
self
.
assertTrue
(
resp
.
closed
)
self
.
assertTrue
(
resp
.
closed
)
def
test_mixed_reads
(
self
):
# readline() should update the remaining length, so that read() knows
# how much data is left and does not raise IncompleteRead
body
=
"HTTP/1.1 200 Ok
\
r
\
n
Content-Length: 13
\
r
\
n
\
r
\
n
Text
\
r
\
n
Another"
sock
=
FakeSocket
(
body
)
resp
=
client
.
HTTPResponse
(
sock
)
resp
.
begin
()
self
.
assertEqual
(
resp
.
readline
(),
b'Text
\
r
\
n
'
)
self
.
assertFalse
(
resp
.
isclosed
())
self
.
assertEqual
(
resp
.
read
(),
b'Another'
)
self
.
assertTrue
(
resp
.
isclosed
())
self
.
assertFalse
(
resp
.
closed
)
resp
.
close
()
self
.
assertTrue
(
resp
.
closed
)
def
test_partial_readintos
(
self
):
def
test_partial_readintos
(
self
):
# if we have
a length, the system knows when to close itself
# if we have
Content-Length, HTTPResponse knows when to close itself,
#
same behaviour than
when we read the whole thing with read()
#
the same behaviour as
when we read the whole thing with read()
body
=
"HTTP/1.1 200 Ok
\
r
\
n
Content-Length: 4
\
r
\
n
\
r
\
n
Text"
body
=
"HTTP/1.1 200 Ok
\
r
\
n
Content-Length: 4
\
r
\
n
\
r
\
n
Text"
sock
=
FakeSocket
(
body
)
sock
=
FakeSocket
(
body
)
resp
=
client
.
HTTPResponse
(
sock
)
resp
=
client
.
HTTPResponse
(
sock
)
...
@@ -827,7 +842,7 @@ class BasicTest(TestCase):
...
@@ -827,7 +842,7 @@ class BasicTest(TestCase):
resp
.
begin
()
resp
.
begin
()
self
.
assertEqual
(
resp
.
read
(),
expected
)
self
.
assertEqual
(
resp
.
read
(),
expected
)
# we should have reached the end of the file
# we should have reached the end of the file
self
.
assertEqual
(
sock
.
file
.
read
(
100
),
b""
)
#we read to the end
self
.
assertEqual
(
sock
.
file
.
read
(),
b""
)
#we read to the end
resp
.
close
()
resp
.
close
()
def
test_chunked_sync
(
self
):
def
test_chunked_sync
(
self
):
...
@@ -839,19 +854,65 @@ class BasicTest(TestCase):
...
@@ -839,19 +854,65 @@ class BasicTest(TestCase):
resp
.
begin
()
resp
.
begin
()
self
.
assertEqual
(
resp
.
read
(),
expected
)
self
.
assertEqual
(
resp
.
read
(),
expected
)
# the file should now have our extradata ready to be read
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(
100
),
extradata
.
encode
(
"ascii"
))
#we read to the end
self
.
assertEqual
(
sock
.
file
.
read
(),
extradata
.
encode
(
"ascii"
))
#we read to the end
resp
.
close
()
resp
.
close
()
def
test_content_length_sync
(
self
):
def
test_content_length_sync
(
self
):
"""Check that we don't read past the end of the Content-Length stream"""
"""Check that we don't read past the end of the Content-Length stream"""
extradata
=
"extradata"
extradata
=
b"extradata"
expected
=
b"Hello123
\
r
\
n
"
sock
=
FakeSocket
(
b'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 10
\
r
\
n
\
r
\
n
'
+
expected
+
extradata
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
.
begin
()
self
.
assertEqual
(
resp
.
read
(),
expected
)
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(),
extradata
)
#we read to the end
resp
.
close
()
def
test_readlines_content_length
(
self
):
extradata
=
b"extradata"
expected
=
b"Hello123
\
r
\
n
"
sock
=
FakeSocket
(
b'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 10
\
r
\
n
\
r
\
n
'
+
expected
+
extradata
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
.
begin
()
self
.
assertEqual
(
resp
.
readlines
(
2000
),
[
expected
])
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(),
extradata
)
#we read to the end
resp
.
close
()
def
test_read1_content_length
(
self
):
extradata
=
b"extradata"
expected
=
b"Hello123
\
r
\
n
"
sock
=
FakeSocket
(
b'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 10
\
r
\
n
\
r
\
n
'
+
expected
+
extradata
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
.
begin
()
self
.
assertEqual
(
resp
.
read1
(
2000
),
expected
)
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(),
extradata
)
#we read to the end
resp
.
close
()
def
test_readline_bound_content_length
(
self
):
extradata
=
b"extradata"
expected
=
b"Hello123
\
r
\
n
"
sock
=
FakeSocket
(
b'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 10
\
r
\
n
\
r
\
n
'
+
expected
+
extradata
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
.
begin
()
self
.
assertEqual
(
resp
.
readline
(
10
),
expected
)
self
.
assertEqual
(
resp
.
readline
(
10
),
b""
)
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(),
extradata
)
#we read to the end
resp
.
close
()
def
test_read1_bound_content_length
(
self
):
extradata
=
b"extradata"
expected
=
b"Hello123
\
r
\
n
"
expected
=
b"Hello123
\
r
\
n
"
sock
=
FakeSocket
(
'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 10
\
r
\
n
\
r
\
n
Hello123
\
r
\
n
'
+
extradata
)
sock
=
FakeSocket
(
b'HTTP/1.1 200 OK
\
r
\
n
Content-Length: 30
\
r
\
n
\
r
\
n
'
+
expected
*
3
+
extradata
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
=
client
.
HTTPResponse
(
sock
,
method
=
"GET"
)
resp
.
begin
()
resp
.
begin
()
self
.
assertEqual
(
resp
.
read1
(
20
),
expected
*
2
)
self
.
assertEqual
(
resp
.
read
(),
expected
)
self
.
assertEqual
(
resp
.
read
(),
expected
)
# the file should now have our extradata ready to be read
# the file should now have our extradata ready to be read
self
.
assertEqual
(
sock
.
file
.
read
(
100
),
extradata
.
encode
(
"ascii"
)
)
#we read to the end
self
.
assertEqual
(
sock
.
file
.
read
(
),
extradata
)
#we read to the end
resp
.
close
()
resp
.
close
()
class
ExtendedReadTest
(
TestCase
):
class
ExtendedReadTest
(
TestCase
):
...
...
Misc/NEWS
View file @
ce911c3f
...
@@ -91,6 +91,10 @@ Core and Builtins
...
@@ -91,6 +91,10 @@ Core and Builtins
Library
Library
-------
-------
- Issue #26499: Account for remaining Content-Length in
HTTPResponse.readline() and read1(). Based on patch by Silent Ghost.
Also document that HTTPResponse now supports these methods.
- Issue #25320: Handle sockets in directories unittest discovery is scanning.
- Issue #25320: Handle sockets in directories unittest discovery is scanning.
Patch from Victor van den Elzen.
Patch from Victor van den Elzen.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment