77httplib/http.client.
88"""
99import logging
10+ import weakref
1011import zlib
1112
1213from ..common .decoder import DeflateDecoder
@@ -22,7 +23,7 @@ class HTTP11Response(object):
2223 provides access to the response headers and the entity body. The response
2324 is an iterable object and can be used in a with statement.
2425 """
25- def __init__ (self , code , reason , headers , sock ):
26+ def __init__ (self , code , reason , headers , sock , connection = None ):
2627 #: The reason phrase returned by the server.
2728 self .reason = reason
2829
@@ -74,6 +75,17 @@ def __init__(self, code, reason, headers, sock):
7475 else :
7576 self ._decompressobj = None
7677
78+ # This is a reference that allows for the Response class to tell the
79+ # parent connection object to throw away its socket object. This is to
80+ # be used when the connection is genuinely closed, so that the user
81+ # can keep using the Connection object.
82+ # Strictly, we take a weakreference to this so that we don't set up a
83+ # reference cycle.
84+ if connection is not None :
85+ self ._parent = weakref .ref (connection )
86+ else :
87+ self ._parent = None
88+
7789 self ._buffered_data = b''
7890 self ._chunker = None
7991
@@ -115,8 +127,10 @@ def read(self, amt=None, decode_content=True):
115127 if self ._length is not None :
116128 amt = min (amt , self ._length )
117129
118- # If we are now going to read nothing, exit early.
130+ # If we are now going to read nothing, exit early. We still need to
131+ # close the socket.
119132 if not amt :
133+ self .close (socket_close = self ._expect_close )
120134 return b''
121135
122136 # Now, issue reads until we read that length. This is to account for
@@ -136,7 +150,7 @@ def read(self, amt=None, decode_content=True):
136150 # but if we were expecting the remote end to close then it's ok.
137151 if not chunk :
138152 if self ._length is not None or not self ._expect_close :
139- self .close ()
153+ self .close (socket_close = True )
140154 raise ConnectionResetError ("Remote end hung up!" )
141155
142156 break
@@ -167,7 +181,7 @@ def read(self, amt=None, decode_content=True):
167181 # We're at the end. Close the connection. Explicit check for zero here
168182 # because self._length might be None.
169183 if end_of_request :
170- self .close ()
184+ self .close (socket_close = self . _expect_close )
171185
172186 return data
173187
@@ -204,6 +218,7 @@ def read_chunked(self, decode_content=True):
204218 if decode_content and self ._decompressobj :
205219 yield self ._decompressobj .flush ()
206220
221+ self .close (socket_close = self ._expect_close )
207222 break
208223
209224 # Then read that many bytes.
@@ -225,14 +240,23 @@ def read_chunked(self, decode_content=True):
225240
226241 return
227242
228- def close (self ):
243+ def close (self , socket_close = False ):
229244 """
230- Close the response. In effect this closes the backing socket.
245+ Close the response. This causes the Response to lose access to the
246+ backing socket. In some cases, it can also cause the backing connection
247+ to be torn down.
231248
249+ :param socket_close: Whether to close the backing socket.
232250 :returns: Nothing.
233251 """
234- # FIXME: This should notify the parent connection object if possible.
235- self ._sock .close ()
252+ if socket_close and self ._parent is not None :
253+ # The double call is necessary because we need to dereference the
254+ # weakref. If the weakref is no longer valid, that's fine, there's
255+ # no connection object to tell.
256+ parent = self ._parent ()
257+ if parent is not None :
258+ parent .close ()
259+
236260 self ._sock = None
237261
238262 def _read_expect_closed (self , decode_content ):
@@ -253,7 +277,7 @@ def _read_expect_closed(self, decode_content):
253277 else :
254278 chunks .append (chunk )
255279
256- self .close ()
280+ self .close (socket_close = True )
257281
258282 # We may need to decompress the data.
259283 data = b'' .join (chunks )
@@ -283,7 +307,7 @@ def _normal_read_chunked(self, amt, decode_content):
283307 try :
284308 chunk = next (self ._chunker )
285309 except StopIteration :
286- self .close ()
310+ self .close (socket_close = self . _expect_close )
287311 break
288312
289313 current_amount += len (chunk )
0 commit comments