33
44
55class Socket :
6- def __init__ (self ):
6+ def __init__ (self , read_data = b"HTTP/1.1 200 OK \r \n \r \n " ):
77 self ._write_buffer = io .BytesIO ()
8- self ._read_buffer = io .BytesIO (b"HTTP/1.0 200 OK \r \n \r \n " )
8+ self ._read_buffer = io .BytesIO (read_data )
99
1010 def connect (self , address ):
1111 pass
@@ -16,6 +16,15 @@ def write(self, buf):
1616 def readline (self ):
1717 return self ._read_buffer .readline ()
1818
19+ def read (self , size = - 1 ):
20+ return self ._read_buffer .read (size )
21+
22+ def readinto (self , buf ):
23+ return self ._read_buffer .readinto (buf )
24+
25+ def close (self ):
26+ pass
27+
1928
2029class socket :
2130 AF_INET = 2
@@ -43,7 +52,7 @@ def test_simple_get():
4352 response = requests .request ("GET" , "http://example.com" )
4453
4554 assert response .raw ._write_buffer .getvalue () == (
46- b"GET / HTTP/1.0 \r \n " + b"Connection: close\r \n " + b"Host: example.com\r \n \r \n "
55+ b"GET / HTTP/1.1 \r \n " + b"Connection: close\r \n " + b"Host: example.com\r \n \r \n "
4756 ), format_message (response )
4857
4958
@@ -53,7 +62,7 @@ def test_get_auth():
5362 )
5463
5564 assert response .raw ._write_buffer .getvalue () == (
56- b"GET / HTTP/1.0 \r \n "
65+ b"GET / HTTP/1.1 \r \n "
5766 + b"Host: example.com\r \n "
5867 + b"Authorization: Basic dGVzdC11c2VybmFtZTp0ZXN0LXBhc3N3b3Jk\r \n "
5968 + b"Connection: close\r \n \r \n "
@@ -64,7 +73,7 @@ def test_get_custom_header():
6473 response = requests .request ("GET" , "http://example.com" , headers = {"User-Agent" : "test-agent" })
6574
6675 assert response .raw ._write_buffer .getvalue () == (
67- b"GET / HTTP/1.0 \r \n "
76+ b"GET / HTTP/1.1 \r \n "
6877 + b"User-Agent: test-agent\r \n "
6978 + b"Host: example.com\r \n "
7079 + b"Connection: close\r \n \r \n "
@@ -75,7 +84,7 @@ def test_post_json():
7584 response = requests .request ("GET" , "http://example.com" , json = "test" )
7685
7786 assert response .raw ._write_buffer .getvalue () == (
78- b"GET / HTTP/1.0 \r \n "
87+ b"GET / HTTP/1.1 \r \n "
7988 + b"Connection: close\r \n "
8089 + b"Content-Type: application/json\r \n "
8190 + b"Host: example.com\r \n "
@@ -91,7 +100,7 @@ def chunks():
91100 response = requests .request ("GET" , "http://example.com" , data = chunks ())
92101
93102 assert response .raw ._write_buffer .getvalue () == (
94- b"GET / HTTP/1.0 \r \n "
103+ b"GET / HTTP/1.1 \r \n "
95104 + b"Transfer-Encoding: chunked\r \n "
96105 + b"Host: example.com\r \n "
97106 + b"Connection: close\r \n \r \n "
@@ -106,7 +115,7 @@ def test_overwrite_get_headers():
106115 )
107116
108117 assert response .raw ._write_buffer .getvalue () == (
109- b"GET / HTTP/1.0 \r \n " + b"Connection: keep-alive\r \n " + b"Host: test.com\r \n \r \n "
118+ b"GET / HTTP/1.1 \r \n " + b"Connection: keep-alive\r \n " + b"Host: test.com\r \n \r \n "
110119 ), format_message (response )
111120
112121
@@ -119,7 +128,7 @@ def test_overwrite_post_json_headers():
119128 )
120129
121130 assert response .raw ._write_buffer .getvalue () == (
122- b"GET / HTTP/1.0 \r \n "
131+ b"GET / HTTP/1.1 \r \n "
123132 + b"Connection: close\r \n "
124133 + b"Content-Length: 10\r \n "
125134 + b"Content-Type: text/plain\r \n "
@@ -137,7 +146,7 @@ def chunks():
137146 )
138147
139148 assert response .raw ._write_buffer .getvalue () == (
140- b"GET / HTTP/1.0 \r \n "
149+ b"GET / HTTP/1.1 \r \n "
141150 + b"Host: example.com\r \n "
142151 + b"Content-Length: 4\r \n "
143152 + b"Connection: close\r \n \r \n "
@@ -153,6 +162,70 @@ def test_do_not_modify_headers_argument():
153162 assert do_not_modify_this_dict == {}, do_not_modify_this_dict
154163
155164
165+ def test_content_length_via_content ():
166+ socket .socket = lambda * a , ** k : Socket (
167+ read_data = b"HTTP/1.1 200 OK\r \n Content-Length: 5\r \n \r \n hello"
168+ )
169+ response = requests .request ("GET" , "http://example.com" )
170+ assert response .content == b"hello"
171+ assert response .headers ["Content-Length" ] == "5"
172+ socket .socket = lambda * a , ** k : Socket ()
173+
174+
175+ def test_chunked_response_raises ():
176+ socket .socket = lambda * a , ** k : Socket (
177+ read_data = b"HTTP/1.1 200 OK\r \n Transfer-Encoding: chunked\r \n \r \n 5\r \n hello\r \n 0\r \n \r \n "
178+ )
179+ raised = False
180+ try :
181+ requests .request ("GET" , "http://example.com" )
182+ except ValueError as e :
183+ raised = True
184+ if "Unsupported" not in str (e ):
185+ raise
186+ if not raised :
187+ raise AssertionError ("expected ValueError for chunked response" )
188+ socket .socket = lambda * a , ** k : Socket ()
189+
190+
191+ def test_raw_open_before_content ():
192+ socket .socket = lambda * a , ** k : Socket (
193+ read_data = b"HTTP/1.1 200 OK\r \n Content-Length: 5\r \n \r \n hello"
194+ )
195+ response = requests .request ("GET" , "http://example.com" )
196+ assert response .raw is not None
197+ assert response .raw .read (1 ) == b"h"
198+ socket .socket = lambda * a , ** k : Socket ()
199+
200+
201+ def test_raw_incremental_content_length ():
202+ socket .socket = lambda * a , ** k : Socket (
203+ read_data = b"HTTP/1.1 200 OK\r \n Content-Length: 10\r \n \r \n abcdefghij"
204+ )
205+ response = requests .request ("GET" , "http://example.com" )
206+ assert response .raw .read (3 ) == b"abc"
207+ assert response .raw .read (3 ) == b"def"
208+ assert response .content == b"ghij"
209+ assert response .raw is None
210+ socket .socket = lambda * a , ** k : Socket ()
211+
212+
213+ def test_raw_readinto_content_length ():
214+ socket .socket = lambda * a , ** k : Socket (
215+ read_data = b"HTTP/1.1 200 OK\r \n Content-Length: 10\r \n \r \n abcdefghij"
216+ )
217+ response = requests .request ("GET" , "http://example.com" )
218+ buf = bytearray (3 )
219+ result = b""
220+ while True :
221+ n = response .raw .readinto (buf )
222+ if n == 0 :
223+ break
224+ result += buf if n == 3 else buf [:n ]
225+ assert result == b"abcdefghij"
226+ socket .socket = lambda * a , ** k : Socket ()
227+
228+
156229test_simple_get ()
157230test_get_auth ()
158231test_get_custom_header ()
@@ -162,3 +235,8 @@ def test_do_not_modify_headers_argument():
162235test_overwrite_post_json_headers ()
163236test_overwrite_post_chunked_data_headers ()
164237test_do_not_modify_headers_argument ()
238+ test_content_length_via_content ()
239+ test_chunked_response_raises ()
240+ test_raw_open_before_content ()
241+ test_raw_incremental_content_length ()
242+ test_raw_readinto_content_length ()
0 commit comments