Show More
@@ -171,6 +171,14 b' class HTTPResponse(object):' | |||||
171 | logger.info('cl: %r body: %r', self._content_len, self._body) |
|
171 | logger.info('cl: %r body: %r', self._content_len, self._body) | |
172 | try: |
|
172 | try: | |
173 | data = self.sock.recv(INCOMING_BUFFER_SIZE) |
|
173 | data = self.sock.recv(INCOMING_BUFFER_SIZE) | |
|
174 | # If the socket was readable and no data was read, that | |||
|
175 | # means the socket was closed. If this isn't a | |||
|
176 | # _CLOSE_IS_END socket, then something is wrong if we're | |||
|
177 | # here (we shouldn't enter _select() if the response is | |||
|
178 | # complete), so abort. | |||
|
179 | if not data and self._content_len != _LEN_CLOSE_IS_END: | |||
|
180 | raise HTTPRemoteClosedError( | |||
|
181 | 'server appears to have closed the socket mid-response') | |||
174 | except socket.sslerror, e: |
|
182 | except socket.sslerror, e: | |
175 | if e.args[0] != socket.SSL_ERROR_WANT_READ: |
|
183 | if e.args[0] != socket.SSL_ERROR_WANT_READ: | |
176 | raise |
|
184 | raise | |
@@ -693,6 +701,11 b' class BadRequestData(httplib.HTTPExcepti' | |||||
693 | class HTTPProxyConnectFailedException(httplib.HTTPException): |
|
701 | class HTTPProxyConnectFailedException(httplib.HTTPException): | |
694 | """Connecting to the HTTP proxy failed.""" |
|
702 | """Connecting to the HTTP proxy failed.""" | |
695 |
|
703 | |||
|
704 | ||||
696 | class HTTPStateError(httplib.HTTPException): |
|
705 | class HTTPStateError(httplib.HTTPException): | |
697 | """Invalid internal state encountered.""" |
|
706 | """Invalid internal state encountered.""" | |
|
707 | ||||
|
708 | ||||
|
709 | class HTTPRemoteClosedError(httplib.HTTPException): | |||
|
710 | """The server closed the remote socket in the middle of a response.""" | |||
698 | # no-check-code |
|
711 | # no-check-code |
@@ -380,6 +380,21 b' dotencode' | |||||
380 | con.request('GET', '/') |
|
380 | con.request('GET', '/') | |
381 | self.assertEqual(2, len(sockets)) |
|
381 | self.assertEqual(2, len(sockets)) | |
382 |
|
382 | |||
|
383 | def test_server_closes_before_end_of_body(self): | |||
|
384 | con = http.HTTPConnection('1.2.3.4:80') | |||
|
385 | con._connect() | |||
|
386 | s = con.sock | |||
|
387 | s.data = ['HTTP/1.1 200 OK\r\n', | |||
|
388 | 'Server: BogusServer 1.0\r\n', | |||
|
389 | 'Connection: Keep-Alive\r\n', | |||
|
390 | 'Content-Length: 16', | |||
|
391 | '\r\n\r\n', | |||
|
392 | 'You can '] # Note: this is shorter than content-length | |||
|
393 | s.close_on_empty = True | |||
|
394 | con.request('GET', '/') | |||
|
395 | r1 = con.getresponse() | |||
|
396 | self.assertRaises(http.HTTPRemoteClosedError, r1.read) | |||
|
397 | ||||
383 | def test_no_response_raises_response_not_ready(self): |
|
398 | def test_no_response_raises_response_not_ready(self): | |
384 | con = http.HTTPConnection('foo') |
|
399 | con = http.HTTPConnection('foo') | |
385 | self.assertRaises(http.httplib.ResponseNotReady, con.getresponse) |
|
400 | self.assertRaises(http.httplib.ResponseNotReady, con.getresponse) |
@@ -134,4 +134,20 b' class ChunkedTransferTest(util.HttpTestB' | |||||
134 | con.request('GET', '/') |
|
134 | con.request('GET', '/') | |
135 | self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n', |
|
135 | self.assertStringEqual('hi there\nthere\nthere\nthere\nthere\n', | |
136 | con.getresponse().read()) |
|
136 | con.getresponse().read()) | |
|
137 | ||||
|
138 | def testChunkedDownloadEarlyHangup(self): | |||
|
139 | con = http.HTTPConnection('1.2.3.4:80') | |||
|
140 | con._connect() | |||
|
141 | sock = con.sock | |||
|
142 | broken = chunkedblock('hi'*20)[:-1] | |||
|
143 | sock.data = ['HTTP/1.1 200 OK\r\n', | |||
|
144 | 'Server: BogusServer 1.0\r\n', | |||
|
145 | 'transfer-encoding: chunked', | |||
|
146 | '\r\n\r\n', | |||
|
147 | broken, | |||
|
148 | ] | |||
|
149 | sock.close_on_empty = True | |||
|
150 | con.request('GET', '/') | |||
|
151 | resp = con.getresponse() | |||
|
152 | self.assertRaises(http.HTTPRemoteClosedError, resp.read) | |||
137 | # no-check-code |
|
153 | # no-check-code |
General Comments 0
You need to be logged in to leave comments.
Login now