How does Twisted get response in client?

Viewed 88

I'm reading Twisted Network Programming Essentials. In Chapter 5, there is this code:

# encoding: utf-8
import sys

from twisted.internet import reactor
from twisted.internet.defer import Deferred
from twisted.internet.protocol import Protocol
from twisted.web.client import Agent

class ResourcePrinter(Protocol):
    def __init__(self, finished):
        self.finished = finished

    def dataReceived(self, data):
        '''
        data seems comes from response not transport
        '''
        print data

    def connectionLost(self, reason):
        self.finished.callback(None) # Fire with None, no callback in deferred: finished


def printResource(response):
    finished = Deferred()
    print "idf: ", id(finished)
    # Dispatch IProtocol to handle response
    response.deliverBody(ResourcePrinter(finished))
    return finished

def printError(failure):
    print >> sys.stderr, failure

def stop(result):
    print type(result) # Result is None, not return value from printResource, why?
    reactor.stop()


if len(sys.argv) != 2:
    print >> sys.stderr, "Usage: python e5-3.py URL"
    exit(1)

agent = Agent(reactor)
d = agent.request("GET", sys.argv[1])
d.addCallbacks(printResource, printError)
d.addBoth(stop)

reactor.run()
  1. Why there are two deferred? → d and finished, how are they combined?
  2. The return value of printResource is finished, why not pass to callback stop? (The arg result is None.)
  3. What is the flow of the response, where does it begin and end? The flow seems to be that, d gets the response in chunks and passes it to callback printResource. In printResource, it dispatches to IProtocol to handle it. How does it work? Usually, IProtocol receives data from ITransport, but here it seems not.
0 Answers
Related