Ticket #6104: get-page-cancel.diff
| File get-page-cancel.diff, 6.0 KB (added by luks, 8 months ago) |
|---|
-
twisted/web/client.py
=== modified file 'twisted/web/client.py'
311 311 def __init__(self, url, method='GET', postdata=None, headers=None, 312 312 agent="Twisted PageGetter", timeout=0, cookies=None, 313 313 followRedirect=True, redirectLimit=20, 314 afterFoundGet=False ):314 afterFoundGet=False, canceller=None): 315 315 self.followRedirect = followRedirect 316 316 self.redirectLimit = redirectLimit 317 317 self._redirectCount = 0 … … 336 336 337 337 self.waiting = 1 338 338 self._disconnectedDeferred = defer.Deferred() 339 self.deferred = defer.Deferred( )339 self.deferred = defer.Deferred(canceller) 340 340 # Make sure the first callback on the result Deferred pauses the 341 341 # callback chain until the request connection is closed. 342 342 self.deferred.addBoth(self._waitForDisconnect) … … 408 408 result has yet been provided to the result Deferred, provide the 409 409 connection failure reason as an error result. 410 410 """ 411 if self.waiting: 412 self.waiting = 0 413 # If the connection attempt failed, there is nothing more to 414 # disconnect, so just fire that Deferred now. 415 self._disconnectedDeferred.callback(None) 416 self.deferred.errback(reason) 411 self.noPage(reason) 412 # If the connection attempt failed, there is nothing more to 413 # disconnect, so just fire that Deferred now. 414 self._disconnectedDeferred.callback(None) 417 415 418 416 419 417 … … 427 425 method='GET', postdata=None, headers=None, 428 426 agent="Twisted client", supportPartial=0, 429 427 timeout=0, cookies=None, followRedirect=1, 430 redirectLimit=20, afterFoundGet=False): 428 redirectLimit=20, afterFoundGet=False, 429 canceller=None): 431 430 self.requestedPartial = 0 432 431 if isinstance(fileOrName, types.StringTypes): 433 432 self.fileName = fileOrName … … 445 444 self, url, method=method, postdata=postdata, headers=headers, 446 445 agent=agent, timeout=timeout, cookies=cookies, 447 446 followRedirect=followRedirect, redirectLimit=redirectLimit, 448 afterFoundGet=afterFoundGet )447 afterFoundGet=afterFoundGet, canceller=canceller) 449 448 450 449 451 450 def gotHeaders(self, headers): … … 596 595 597 596 @return: The factory created by C{factoryFactory} 598 597 """ 598 def cancel(d): 599 factory.noPage(defer.CancelledError()) 600 connector.disconnect() 599 601 scheme, host, port, path = _parse(url) 600 factory = factoryFactory(url, *args, **kwargs)602 factory = factoryFactory(url, canceller=cancel, *args, **kwargs) 601 603 if scheme == 'https': 602 604 from twisted.internet import ssl 603 605 if contextFactory is None: 604 606 contextFactory = ssl.ClientContextFactory() 605 reactor.connectSSL(host, port, factory, contextFactory)607 connector = reactor.connectSSL(host, port, factory, contextFactory) 606 608 else: 607 reactor.connectTCP(host, port, factory)609 connector = reactor.connectTCP(host, port, factory) 608 610 return factory 609 611 610 612 … … 615 617 Download a page. Return a deferred, which will callback with a 616 618 page (as a string) or errback with a description of the error. 617 619 620 If the deferred is cancelled before the request completes, the 621 connection is closed and the deferred will fire with a 622 L{defer.CancelledError}. 623 618 624 See L{HTTPClientFactory} to see what extra arguments can be passed. 619 625 """ 620 626 return _makeGetterFactory( … … 628 634 """ 629 635 Download a web page to a file. 630 636 637 Download a page. Return a deferred, which will callback with None 638 or errback with a description of the error. 639 640 If the deferred is cancelled before the request completes, the 641 connection is closed and the deferred will fire with a 642 L{defer.CancelledError}. 643 631 644 @param file: path to file on filesystem, or file-like object. 632 645 633 See HTTPDownloaderto see what extra args can be passed.646 See L{HTTPDownloader} to see what extra args can be passed. 634 647 """ 635 648 factoryFactory = lambda url, *a, **kw: HTTPDownloader(url, file, *a, **kw) 636 649 return _makeGetterFactory( -
twisted/web/test/test_webclient.py
=== modified file 'twisted/web/test/test_webclient.py'
507 507 defer.TimeoutError) 508 508 509 509 510 def test_getPageCancelImmediately(self): 511 """ 512 Call L{getPage} and cancel it before it has chance to try to 513 connect to the server. The L{Deferred} returned by L{getPage} 514 fails with L{defer.CancelledError}. 515 """ 516 d = client.getPage(self.getURL("wait"), timeout=10) 517 d.cancel() 518 return self.assertFailure(d, defer.CancelledError) 519 520 521 def test_getPageCancelLater(self): 522 """ 523 Call L{getPage} and cancel it after it has connected to the server, 524 but before it was able to deliver the results. The L{Deferred} 525 returned by L{getPage} fails with L{defer.CancelledError}. 526 """ 527 d = client.getPage(self.getURL("wait"), timeout=10) 528 reactor.callLater(0.01, d.cancel) 529 return self.assertFailure(d, defer.CancelledError) 530 531 532 def test_getPageCancelAfter(self): 533 """ 534 Call L{getPage} and attempt to cancel it after it has delivered 535 the results. The cancellation is ignored and the L{Deferred} 536 returned by L{getPage} is called back with the page contents. 537 """ 538 d = client.getPage(self.getURL("file")) 539 def cancelRequest(content): 540 d.cancel() 541 return content 542 d.addCallback(cancelRequest) 543 d.addCallback(self.assertEqual, "0123456789") 544 return d 545 546 510 547 def testDownloadPage(self): 511 548 downloads = [] 512 549 downloadData = [("file", self.mktemp(), "0123456789"),
