@@ -36,6 +36,44 @@ def urlopen(url, data=None, proxies=None):
3636 else :
3737 return opener .open (url , data )
3838
39+
40+ class FakeHTTPMixin (object ):
41+ def fakehttp (self , fakedata ):
42+ class FakeSocket (io .BytesIO ):
43+ io_refs = 1
44+
45+ def sendall (self , str ):
46+ pass
47+
48+ def makefile (self , * args , ** kwds ):
49+ self .io_refs += 1
50+ return self
51+
52+ def read (self , amt = None ):
53+ if self .closed :
54+ return b""
55+ return io .BytesIO .read (self , amt )
56+
57+ def readline (self , length = None ):
58+ if self .closed :
59+ return b""
60+ return io .BytesIO .readline (self , length )
61+
62+ def close (self ):
63+ self .io_refs -= 1
64+ if self .io_refs == 0 :
65+ io .BytesIO .close (self )
66+
67+ class FakeHTTPConnection (http .client .HTTPConnection ):
68+ def connect (self ):
69+ self .sock = FakeSocket (fakedata )
70+ self ._connection_class = http .client .HTTPConnection
71+ http .client .HTTPConnection = FakeHTTPConnection
72+
73+ def unfakehttp (self ):
74+ http .client .HTTPConnection = self ._connection_class
75+
76+
3977class urlopen_FileTests (unittest .TestCase ):
4078 """Test urlopen() opening a temporary file.
4179
@@ -139,35 +177,9 @@ def test_getproxies_environment_keep_no_proxies(self):
139177 self .env .set ('NO_PROXY' , 'localhost, anotherdomain.com, newdomain.com' )
140178 self .assertTrue (urllib .request .proxy_bypass_environment ('anotherdomain.com' ))
141179
142- class urlopen_HttpTests (unittest .TestCase ):
180+ class urlopen_HttpTests (unittest .TestCase , FakeHTTPMixin ):
143181 """Test urlopen() opening a fake http connection."""
144182
145- def fakehttp (self , fakedata ):
146- class FakeSocket (io .BytesIO ):
147- io_refs = 1
148- def sendall (self , str ): pass
149- def makefile (self , * args , ** kwds ):
150- self .io_refs += 1
151- return self
152- def read (self , amt = None ):
153- if self .closed : return b""
154- return io .BytesIO .read (self , amt )
155- def readline (self , length = None ):
156- if self .closed : return b""
157- return io .BytesIO .readline (self , length )
158- def close (self ):
159- self .io_refs -= 1
160- if self .io_refs == 0 :
161- io .BytesIO .close (self )
162- class FakeHTTPConnection (http .client .HTTPConnection ):
163- def connect (self ):
164- self .sock = FakeSocket (fakedata )
165- self ._connection_class = http .client .HTTPConnection
166- http .client .HTTPConnection = FakeHTTPConnection
167-
168- def unfakehttp (self ):
169- http .client .HTTPConnection = self ._connection_class
170-
171183 def check_read (self , ver ):
172184 self .fakehttp (b"HTTP/" + ver + b" 200 OK\r \n \r \n Hello!" )
173185 try :
@@ -394,6 +406,48 @@ def hooktester(count, block_size, total_size, _report=report):
394406 self .assertEqual (report [0 ][1 ], 8192 )
395407 self .assertEqual (report [0 ][2 ], 8193 )
396408
409+
410+ class urlretrieve_HttpTests (unittest .TestCase , FakeHTTPMixin ):
411+ """Test urllib.urlretrieve() using fake http connections"""
412+
413+ def test_short_content_raises_ContentTooShortError (self ):
414+ self .fakehttp (b'''HTTP/1.1 200 OK
415+ Date: Wed, 02 Jan 2008 03:03:54 GMT
416+ Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
417+ Connection: close
418+ Content-Length: 100
419+ Content-Type: text/html; charset=iso-8859-1
420+
421+ FF
422+ ''' )
423+
424+ def _reporthook (par1 , par2 , par3 ):
425+ pass
426+
427+ with self .assertRaises (urllib .error .ContentTooShortError ):
428+ try :
429+ urllib .request .urlretrieve ('http://example.com/' ,
430+ reporthook = _reporthook )
431+ finally :
432+ self .unfakehttp ()
433+
434+ def test_short_content_raises_ContentTooShortError_without_reporthook (self ):
435+ self .fakehttp (b'''HTTP/1.1 200 OK
436+ Date: Wed, 02 Jan 2008 03:03:54 GMT
437+ Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
438+ Connection: close
439+ Content-Length: 100
440+ Content-Type: text/html; charset=iso-8859-1
441+
442+ FF
443+ ''' )
444+ with self .assertRaises (urllib .error .ContentTooShortError ):
445+ try :
446+ urllib .request .urlretrieve ('http://example.com/' )
447+ finally :
448+ self .unfakehttp ()
449+
450+
397451class QuotingTests (unittest .TestCase ):
398452 """Tests for urllib.quote() and urllib.quote_plus()
399453
@@ -1186,6 +1240,7 @@ def test_main():
11861240 urlopen_FileTests ,
11871241 urlopen_HttpTests ,
11881242 urlretrieve_FileTests ,
1243+ urlretrieve_HttpTests ,
11891244 ProxyTests ,
11901245 QuotingTests ,
11911246 UnquotingTests ,
0 commit comments