Skip to content

Commit ecddc09

Browse files
committed
Explicitly call Twisted transport stopProducing() on HTTP/1.1 timeouts
1 parent f7a48b0 commit ecddc09

File tree

2 files changed

+17
-5
lines changed

2 files changed

+17
-5
lines changed

scrapy/core/downloader/handlers/http11.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ def __init__(self, contextFactory=None, connectTimeout=10, bindAddress=None, poo
193193
self._pool = pool
194194
self._maxsize = maxsize
195195
self._warnsize = warnsize
196+
self._txresponse = None
196197

197198
def _get_agent(self, request, timeout):
198199
bindaddress = request.meta.get('bindaddress') or self._bindAddress
@@ -259,6 +260,11 @@ def _cb_timeout(self, result, request, url, timeout):
259260
if self._timeout_cl.active():
260261
self._timeout_cl.cancel()
261262
return result
263+
# needed for HTTPS requests, otherwise _ResponseReader doesn't
264+
# receive connectionLost()
265+
if self._txresponse:
266+
self._txresponse._transport.stopProducing()
267+
262268
raise TimeoutError("Getting %s took longer than %s seconds." % (url, timeout))
263269

264270
def _cb_latency(self, result, request, start_time):
@@ -294,6 +300,10 @@ def _cancel(_):
294300

295301
d = defer.Deferred(_cancel)
296302
txresponse.deliverBody(_ResponseReader(d, txresponse, request, maxsize, warnsize))
303+
304+
# save response for timeouts
305+
self._txresponse = txresponse
306+
297307
return d
298308

299309
def _cb_bodydone(self, result, request, url):

tests/test_downloader_handlers.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,17 +182,19 @@ def test_redirect_status_head(self):
182182
return d
183183

184184
@defer.inlineCallbacks
185-
def test_timeout_download_from_spider(self):
186-
if self.scheme == 'https':
187-
raise unittest.SkipTest(
188-
'test_timeout_download_from_spider skipped under https')
185+
def test_timeout_download_from_spider_nodata_rcvd(self):
186+
# client connects but no data is received
189187
spider = Spider('foo')
190188
meta = {'download_timeout': 0.2}
191-
# client connects but no data is received
192189
request = Request(self.getURL('wait'), meta=meta)
193190
d = self.download_request(request, spider)
194191
yield self.assertFailure(d, defer.TimeoutError, error.TimeoutError)
192+
193+
@defer.inlineCallbacks
194+
def test_timeout_download_from_spider_server_hangs(self):
195195
# client connects, server send headers and some body bytes but hangs
196+
spider = Spider('foo')
197+
meta = {'download_timeout': 0.2}
196198
request = Request(self.getURL('hang-after-headers'), meta=meta)
197199
d = self.download_request(request, spider)
198200
yield self.assertFailure(d, defer.TimeoutError, error.TimeoutError)

0 commit comments

Comments
 (0)