def handle_descriptor_response(self, response_dict):
if self.file_sender is None: # Expecting Server Info Response
if 'send_sd_blob' not in response_dict:
raise ReflectorRequestError("I don't know whether to send the sd blob or not!")
if response_dict['send_sd_blob'] is True:
self.open_blob_for_reading(self.sd_blob)
self.file_sender = FileSender()
else:
self.received_descriptor_response = True
self.descriptor_needed = response_dict['send_sd_blob']
self.needed_blobs = response_dict.get('needed_blobs', [])
return self.get_blobs_to_send()
else: # Expecting Server Blob Response
if 'received_sd_blob' not in response_dict:
raise ValueError("I don't know if the sd blob made it to the intended destination!")
else:
self.received_descriptor_response = True
if response_dict['received_sd_blob']:
log.info("Sent reflector descriptor %s", self.next_blob_to_send)
else:
log.warning("Reflector failed to receive descriptor %s for",
self.next_blob_to_send)
self.blobs_to_send.append(self.next_blob_to_send)
return self.set_not_uploading()
python类FileSender()的实例源码
def test_transfer(self):
"""
L{basic.FileSender} sends the content of the given file using a
C{IConsumer} interface via C{beginFileTransfer}. It returns a
L{Deferred} which fires with the last byte sent.
"""
source = BytesIO(b"Test content")
consumer = proto_helpers.StringTransport()
sender = basic.FileSender()
d = sender.beginFileTransfer(source, consumer)
sender.resumeProducing()
# resumeProducing only finishes after trying to read at eof
sender.resumeProducing()
self.assertIsNone(consumer.producer)
self.assertEqual(b"t", self.successResultOf(d))
self.assertEqual(b"Test content", consumer.value())
def test_transferMultipleChunks(self):
"""
L{basic.FileSender} reads at most C{CHUNK_SIZE} every time it resumes
producing.
"""
source = BytesIO(b"Test content")
consumer = proto_helpers.StringTransport()
sender = basic.FileSender()
sender.CHUNK_SIZE = 4
d = sender.beginFileTransfer(source, consumer)
# Ideally we would assertNoResult(d) here, but <http://tm.tl/6291>
sender.resumeProducing()
self.assertEqual(b"Test", consumer.value())
sender.resumeProducing()
self.assertEqual(b"Test con", consumer.value())
sender.resumeProducing()
self.assertEqual(b"Test content", consumer.value())
# resumeProducing only finishes after trying to read at eof
sender.resumeProducing()
self.assertEqual(b"t", self.successResultOf(d))
self.assertEqual(b"Test content", consumer.value())
def test_abortedTransfer(self):
"""
The C{Deferred} returned by L{basic.FileSender.beginFileTransfer} fails
with an C{Exception} if C{stopProducing} when the transfer is not
complete.
"""
source = BytesIO(b"Test content")
consumer = proto_helpers.StringTransport()
sender = basic.FileSender()
d = sender.beginFileTransfer(source, consumer)
# Abort the transfer right away
sender.stopProducing()
failure = self.failureResultOf(d)
failure.trap(Exception)
self.assertEqual("Consumer asked us to stop producing",
str(failure.value))
def connectionMade(self):
s = basic.FileSender()
d = s.beginFileTransfer(self.f, self.transport, lambda x: x)
d.addCallback(lambda r: self.transport.loseConnection())
def testSendingEmptyFile(self):
fileSender = basic.FileSender()
consumer = abstract.FileDescriptor()
consumer.connected = 1
emptyFile = StringIO.StringIO('')
d = fileSender.beginFileTransfer(emptyFile, consumer, lambda x: x)
# The producer will be immediately exhausted, and so immediately
# unregistered
self.assertEqual(consumer.producer, None)
# Which means the Deferred from FileSender should have been called
self.failUnless(d.called,
'producer unregistered with deferred being called')
def connectionMade(self):
d = basic.FileSender().beginFileTransfer(file(self.junkPath), self.transport)
d.addErrback(failed)
d.addCallback(lambda ign: self.transport.loseConnection())
def startProducing(self, fd):
self.deferred = basic.FileSender().beginFileTransfer(fd, self)
self.deferred.addBoth(lambda x : self.stopPaging())
def send(self, consumer):
assert not self._send, "Can only call IReadFile.send *once* per instance"
self._send = True
d = basic.FileSender().beginFileTransfer(self.fObj, consumer)
d.addBoth(self._close)
return d
def _sendMessageContent(self, i, fpWrapper, successResponse):
d = self._getMessageFile(i)
def cbMessageFile(info):
if info is None:
# Some error occurred - a failure response has been sent
# already, just give up.
return
self._highest = max(self._highest, int(i))
resp, fp = info
fp = fpWrapper(fp)
self.successResponse(successResponse(resp))
s = basic.FileSender()
d = s.beginFileTransfer(fp, self.transport, self.transformChunk)
def cbFileTransfer(lastsent):
if lastsent != '\n':
line = '\r\n.'
else:
line = '.'
self.sendLine(line)
def ebFileTransfer(err):
self.transport.loseConnection()
log.msg("Unexpected error in _sendMessageContent:")
log.err(err)
d.addCallback(cbFileTransfer)
d.addErrback(ebFileTransfer)
return d
return self._longOperation(d.addCallback(cbMessageFile))
def startUp(self):
self.createTempFile()
if self.fh != -1:
self.filesender = basic.FileSender()
self.filesender.beginFileTransfer(self.msg, self)
def smtpState_data(self, code, resp):
s = basic.FileSender()
s.beginFileTransfer(
self.getMailData(), self.transport, self.transformChunk
).addCallback(self.finishedFileTransfer)
self._expected = SUCCESS
self._okresponse = self.smtpState_msgSent
def smtpState_msgSent(self, code, resp):
if self._from is not None:
self.sentMail(code, resp, len(self.successAddresses),
self.toAddressesResult, self.log)
self.toAddressesResult = []
self._from = None
self.sendLine('RSET')
self._expected = SUCCESS
self._okresponse = self.smtpState_from
##
## Helpers for FileSender
##
def __init__(self, filename, transform=None, delay=0, verbose=False):
self.f = open(filename, 'rb')
self.transform = transform
self.delay = delay
self.producer = FileSender()
self.logger = gogo.Gogo(__name__, verbose=verbose).logger
def connectionMade(self):
s = basic.FileSender()
d = s.beginFileTransfer(self.f, self.transport, lambda x: x)
d.addCallback(lambda r: self.transport.loseConnection())
def testSendingEmptyFile(self):
fileSender = basic.FileSender()
consumer = abstract.FileDescriptor()
consumer.connected = 1
emptyFile = StringIO.StringIO('')
d = fileSender.beginFileTransfer(emptyFile, consumer, lambda x: x)
# The producer will be immediately exhausted, and so immediately
# unregistered
self.assertEqual(consumer.producer, None)
# Which means the Deferred from FileSender should have been called
self.failUnless(d.called,
'producer unregistered with deferred being called')
def connectionMade(self):
d = basic.FileSender().beginFileTransfer(file(self.junkPath), self.transport)
d.addErrback(failed)
d.addCallback(lambda ign: self.transport.loseConnection())
def startProducing(self, fd):
self.deferred = basic.FileSender().beginFileTransfer(fd, self)
self.deferred.addBoth(lambda x : self.stopPaging())
def send(self, consumer):
assert not self._send, "Can only call IReadFile.send *once* per instance"
self._send = True
d = basic.FileSender().beginFileTransfer(self.fObj, consumer)
d.addBoth(self._close)
return d
def _sendMessageContent(self, i, fpWrapper, successResponse):
d = self._getMessageFile(i)
def cbMessageFile(info):
if info is None:
# Some error occurred - a failure response has been sent
# already, just give up.
return
self._highest = max(self._highest, int(i))
resp, fp = info
fp = fpWrapper(fp)
self.successResponse(successResponse(resp))
s = basic.FileSender()
d = s.beginFileTransfer(fp, self.transport, self.transformChunk)
def cbFileTransfer(lastsent):
if lastsent != '\n':
line = '\r\n.'
else:
line = '.'
self.sendLine(line)
def ebFileTransfer(err):
self.transport.loseConnection()
log.msg("Unexpected error in _sendMessageContent:")
log.err(err)
d.addCallback(cbFileTransfer)
d.addErrback(ebFileTransfer)
return d
return self._longOperation(d.addCallback(cbMessageFile))
def startUp(self):
self.createTempFile()
if self.fh != -1:
self.filesender = basic.FileSender()
self.filesender.beginFileTransfer(self.msg, self)
def smtpState_data(self, code, resp):
s = basic.FileSender()
s.beginFileTransfer(
self.getMailData(), self.transport, self.transformChunk
).addCallback(self.finishedFileTransfer)
self._expected = SUCCESS
self._okresponse = self.smtpState_msgSent
def smtpState_msgSent(self, code, resp):
if self._from is not None:
self.sentMail(code, resp, len(self.successAddresses),
self.toAddressesResult, self.log)
self.toAddressesResult = []
self._from = None
self.sendLine('RSET')
self._expected = SUCCESS
self._okresponse = self.smtpState_from
##
## Helpers for FileSender
##
def handle_normal_response(self, response_dict):
if self.file_sender is None: # Expecting Server Info Response
if 'send_blob' not in response_dict:
raise ValueError("I don't know whether to send the blob or not!")
if response_dict['send_blob'] is True:
self.file_sender = FileSender()
return defer.succeed(True)
else:
return self.set_not_uploading()
else: # Expecting Server Blob Response
if 'received_blob' not in response_dict:
raise ValueError("I don't know if the blob made it to the intended destination!")
else:
return self.set_not_uploading()
def handle_normal_response(self, response_dict):
if self.file_sender is None: # Expecting Server Info Response
if 'send_blob' not in response_dict:
raise ValueError("I don't know whether to send the blob or not!")
if response_dict['send_blob'] is True:
self.file_sender = FileSender()
return defer.succeed(True)
else:
return self.set_not_uploading()
else: # Expecting Server Blob Response
if 'received_blob' not in response_dict:
raise ValueError("I don't know if the blob made it to the intended destination!")
else:
return self.set_not_uploading()
def connectionMade(self):
s = basic.FileSender()
d = s.beginFileTransfer(self.f, self.transport, lambda x: x)
d.addCallback(lambda r: self.transport.loseConnection())
def testSendingEmptyFile(self):
fileSender = basic.FileSender()
consumer = abstract.FileDescriptor()
consumer.connected = 1
emptyFile = BytesIO(b'')
d = fileSender.beginFileTransfer(emptyFile, consumer, lambda x: x)
# The producer will be immediately exhausted, and so immediately
# unregistered
self.assertIsNone(consumer.producer)
# Which means the Deferred from FileSender should have been called
self.assertTrue(d.called,
'producer unregistered with deferred being called')
def connectionMade(self):
d = basic.FileSender().beginFileTransfer(open(self.junkPath, 'rb'),
self.transport)
d.addErrback(failed)
d.addCallback(lambda ign: self.transport.loseConnection())
def _gotArticle(self, result):
(index, id, article) = result
self.currentIndex = index
self.sendLine('220 %d %s article' % (index, id))
s = basic.FileSender()
d = s.beginFileTransfer(article, self.transport)
d.addCallback(self.finishedFileTransfer)
##
## Helper for FileSender
##
def _gotBody(self, result):
(index, id, body) = result
self.currentIndex = index
self.sendLine('221 %d %s article retrieved' % (index, id))
self.lastsent = ''
s = basic.FileSender()
d = s.beginFileTransfer(body, self.transport)
d.addCallback(self.finishedFileTransfer)