@@ -112,8 +112,8 @@ def read(self, amt=None, decode_content=True):
112112 # Otherwise, we've been asked to do a bounded read. We should read no
113113 # more than the remaining length, obviously.
114114 # FIXME: Handle cases without _length
115- assert self ._length is not None
116- amt = min (amt , self ._length )
115+ if self ._length is not None :
116+ amt = min (amt , self ._length )
117117
118118 # If we are now going to read nothing, exit early.
119119 if not amt :
@@ -132,28 +132,41 @@ def read(self, amt=None, decode_content=True):
132132 chunk = self ._sock .recv (amt ).tobytes ()
133133
134134 # If we got an empty read, but were expecting more, the remote end
135- # has hung up. Raise an exception.
135+ # has hung up. Raise an exception if we were expecting more data,
136+ # but if we were expecting the remote end to close then it's ok.
136137 if not chunk :
137- self .close ()
138- raise ConnectionResetError ("Remote end hung up!" )
138+ if self ._length is not None or not self ._expect_close :
139+ self .close ()
140+ raise ConnectionResetError ("Remote end hung up!" )
141+
142+ break
139143
140144 to_read -= len (chunk )
141145 chunks .append (chunk )
142146
143147 data = b'' .join (chunks )
144- self ._length -= len (data )
148+ if self ._length is not None :
149+ self ._length -= len (data )
150+
151+ # If we're at the end of the request, we have some cleaning up to do.
152+ # Close the stream, and if necessary flush the buffer. Checking that
153+ # we're at the end is actually obscenely complex: either we've read the
154+ # full content-length or, if we were expecting a closed connection,
155+ # we've had a read shorter than the requested amount. We also have to
156+ # do this before we try to decompress the body.
157+ end_of_request = (self ._length == 0 or
158+ (self ._expect_close and len (data ) < amt ))
145159
146160 # We may need to decode the body.
147161 if decode_content and self ._decompressobj and data :
148162 data = self ._decompressobj .decompress (data )
149163
150- # If we're at the end of the request, we have some cleaning up to do.
151- # Close the stream, and if necessary flush the buffer.
152- if decode_content and self ._decompressobj and not self ._length :
164+ if decode_content and self ._decompressobj and end_of_request :
153165 data += self ._decompressobj .flush ()
154166
155- # We're at the end. Close the connection.
156- if not self ._length :
167+ # We're at the end. Close the connection. Explicit check for zero here
168+ # because self._length might be None.
169+ if end_of_request :
157170 self .close ()
158171
159172 return data
0 commit comments