Пример #1
0
 def _doReadOrWrite(self,
                    selectable,
                    fd,
                    event,
                    POLLIN,
                    POLLOUT,
                    log,
                    faildict=None):
     if not faildict:
         faildict = {
             error.ConnectionDone: failure.Failure(error.ConnectionDone()),
             error.ConnectionLost: failure.Failure(error.ConnectionLost())
         }
     why = None
     inRead = False
     if event & POLL_DISCONNECTED and not (event & POLLIN):
         why = main.CONNECTION_LOST
     else:
         try:
             if event & POLLIN:
                 why = selectable.doRead()
                 inRead = True
             if not why and event & POLLOUT:
                 why = selectable.doWrite()
                 inRead = False
             if not selectable.fileno() == fd:
                 why = error.ConnectionFdescWentAway(
                     'Filedescriptor went away')
                 inRead = False
         except AttributeError as ae:
             if "'NoneType' object has no attribute 'writeHeaders'" not in six.text_type(
                     ae):
                 log.deferr()
                 why = sys.exc_info()[1]
             else:
                 why = None
         except:
             log.deferr()
             why = sys.exc_info()[1]
     if why:
         try:
             self._disconnectSelectable(selectable, why, inRead)
         except RuntimeError:
             pass
    def _sendRequest(self, msg, data):
        """
        Send a request and return a deferred which waits for the result.

        @type msg: L{int}
        @param msg: The request type (e.g., C{FXP_READ}).

        @type data: L{bytes}
        @param data: The body of the request.
        """
        if not self.connected:
            return defer.fail(error.ConnectionLost())

        data = struct.pack('!L', self.counter) + data
        d = defer.Deferred()
        self.openRequests[self.counter] = d
        self.counter += 1
        self.sendPacket(msg, data)
        return d
Пример #3
0
def _disconnectSelectable(selectable, why, isRead, faildict={
    error.ConnectionDone: failure.Failure(error.ConnectionDone()),
    error.ConnectionLost: failure.Failure(error.ConnectionLost())
    }):
    """
    Utility function for disconnecting a selectable.

    Supports half-close notification, isRead should be boolean indicating
    whether error resulted from doRead().
    """
    f = faildict.get(why.__class__)
    if f:
        if (isRead and why.__class__ ==  error.ConnectionDone
            and interfaces.IHalfCloseableDescriptor.providedBy(selectable)):
            selectable.readConnectionLost(f)
        else:
            selectable.connectionLost(f)
    else:
        selectable.connectionLost(failure.Failure(why))
Пример #4
0
 def lostRemote(self, conn=None):
     # the worker went away. There are several possible reasons for this,
     # and they aren't necessarily fatal. For now, kill the build, but
     # TODO: see if we can resume the build when it reconnects.
     log.msg("%s.lostRemote" % self)
     self.conn = None
     self.text = ["lost", "connection"]
     self.results = RETRY
     if self.currentStep and self.currentStep.results is None:
         # this should cause the step to finish.
         log.msg(" stopping currentStep", self.currentStep)
         self.currentStep.interrupt(Failure(error.ConnectionLost()))
     else:
         self.text = ["lost", "connection"]
         self.stopped = True
         if self._acquiringLock:
             lock, access, d = self._acquiringLock
             lock.stopWaitingUntilAvailable(self, access, d)
             d.callback(None)
    def connectionLost(self, reason):
        """
        Called when connection to the remote subsystem was lost.

        Any pending requests are aborted.
        """

        FileTransferBase.connectionLost(self, reason)

        # If there are still requests waiting for responses when the
        # connection is lost, fail them.
        if self.openRequests:

            # Even if our transport was lost "cleanly", our
            # requests were still not cancelled "cleanly".
            requestError = error.ConnectionLost()
            requestError.__cause__ = reason.value
            requestFailure = failure.Failure(requestError)
            while self.openRequests:
                _, deferred = self.openRequests.popitem()
                deferred.errback(requestFailure)
Пример #6
0
 def doRead(self):
     """Poll the connection and process any notifications."""
     with self._db_lock:
         try:
             self.connection.connection.poll()
         except Exception:
             # If the connection goes down then `OperationalError` is raised.
             # It contains no pgcode or pgerror to identify the reason so no
             # special consideration can be made for it. Hence all errors are
             # treated the same, and we assume that the connection is broken.
             #
             # We do NOT return a failure, which would signal to the reactor
             # that the connection is broken in some way, because the reactor
             # will end up removing this instance from its list of selectables
             # but not from its list of readable fds, or something like that.
             # The point is that the reactor's accounting gets muddled. Things
             # work correctly if we manage the disconnection ourselves.
             #
             self.loseConnection(Failure(error.ConnectionLost()))
         else:
             self._process_notifies()
Пример #7
0
 def _handleWrite(self, rc, bytes, evt):
     """
     Returns false if we should stop writing for now
     """
     if self.disconnected or self._writeDisconnected:
         return False
     # XXX: not handling WSAEWOULDBLOCK
     # ("too many outstanding overlapped I/O requests")
     if rc:
         self.connectionLost(
             failure.Failure(
                 error.ConnectionLost(
                     "write error -- %s (%s)" %
                     (errno.errorcode.get(rc, 'unknown'), rc))))
         return False
     else:
         self.offset += bytes
         # If there is nothing left to send,
         if self.offset == len(self.dataBuffer) and not self._tempDataLen:
             self.dataBuffer = ""
             self.offset = 0
             # stop writing
             self.stopWriting()
             # If I've got a producer who is supposed to supply me with data
             if self.producer is not None and ((not self.streamingProducer)
                                               or self.producerPaused):
                 # tell them to supply some more.
                 self.producerPaused = True
                 self.producer.resumeProducing()
             elif self.disconnecting:
                 # But if I was previously asked to let the connection die,
                 # do so.
                 self.connectionLost(failure.Failure(main.CONNECTION_DONE))
             elif self._writeDisconnecting:
                 # I was previously asked to half-close the connection.
                 self._writeDisconnected = True
                 self._closeWriteConnection()
             return False
         else:
             return True
Пример #8
0
    def test_portalRejectedSenderAddress(self):
        """
        Test that a C{MAIL FROM} command with an address rejected by an
        L{smtp.SMTP} instance's portal is responded to with the correct error
        code.
        """
        class DisallowAnonymousAccess(object):
            """
            Checker for L{IAnonymous} which rejects authentication attempts.
            """
            implements(ICredentialsChecker)

            credentialInterfaces = (IAnonymous,)

            def requestAvatarId(self, credentials):
                return defer.fail(UnauthorizedLogin())

        realm = SingletonRealm(smtp.IMessageDelivery, NotImplementedDelivery())
        portal = Portal(realm, [DisallowAnonymousAccess()])
        proto = smtp.SMTP()
        proto.portal = portal
        trans = StringTransport()
        proto.makeConnection(trans)

        # Deal with the necessary preliminaries
        proto.dataReceived('HELO example.com\r\n')
        trans.clear()

        # Try to specify our sender address
        proto.dataReceived('MAIL FROM:<*****@*****.**>\r\n')

        # Clean up the protocol before doing anything that might raise an
        # exception.
        proto.connectionLost(error.ConnectionLost())

        # Make sure that we received exactly the correct response
        self.assertEqual(
            trans.value(),
            '550 Cannot receive from specified address '
            '<*****@*****.**>: Sender not acceptable\r\n')
Пример #9
0
    def dataReceived(self, data, request_counter=None):
        '''Original code from Twisted, hacked for request_counter proxying.
        request_counter is hack for HTTP transport, didn't found cleaner solution how
        to indicate end of request processing in asynchronous manner.
        
        TODO: This would deserve some unit test to be sure that future twisted versions
        will work nicely with this.'''

        if request_counter == None:
            request_counter = RequestCounter()

        #lines  = (self._buffer+data).split(self.delimiter) # Python3
        #self._buffer = lines.pop(-1) # Python3

        # FIXME: need to check the matter of _buffer
        lines = (data).decode('utf-8').split(self.delimiter)  # Python3

        request_counter.set_count(len(lines))
        self.on_finish = request_counter.on_finish

        for line in lines:
            if self.transport.disconnecting:
                request_counter.finish()
                return
            if len(line) > self.MAX_LENGTH:
                request_counter.finish()
                return self.lineLengthExceeded(line)
            elif line:
                try:
                    self.lineReceived(line, request_counter)
                except Exception as exc:
                    request_counter.finish()
                    #log.exception("Processing of message failed")
                    log.warning("Failed message: %s from %s" %
                                (str(exc), self._get_ip()))
                    return error.ConnectionLost('Processing of message failed')

        if len(self._buffer) > self.MAX_LENGTH:
            request_counter.finish()
            return self.lineLengthExceeded(self._buffer)
Пример #10
0
 def _handleRead(self, rc, bytes, evt):
     """
     Returns False if we should stop reading for now
     """
     if self.disconnected:
         return False
     # graceful disconnection
     if (not (rc or bytes)) or rc in (errno.WSAEDISCON, ERROR_HANDLE_EOF):
         self.reactor.removeActiveHandle(self)
         self.readConnectionLost(failure.Failure(main.CONNECTION_DONE))
         return False
     # XXX: not handling WSAEWOULDBLOCK
     # ("too many outstanding overlapped I/O requests")
     elif rc:
         self.connectionLost(failure.Failure(
                             error.ConnectionLost("read error -- %s (%s)" %
                                 (errno.errorcode.get(rc, 'unknown'), rc))))
         return False
     else:
         assert self._readSize == 0
         assert self._readNextBuffer == 0
         self._readSize = bytes
         return self._dispatchData()
Пример #11
0
    def test_deliveryRejectedSenderAddress(self):
        """
        Test that a C{MAIL FROM} command with an address rejected by a
        L{smtp.IMessageDelivery} instance is responded to with the correct
        error code.
        """
        class RejectionDelivery(NotImplementedDelivery):
            """
            Delivery object which rejects all senders as invalid.
            """
            def validateFrom(self, helo, origin):
                raise smtp.SMTPBadSender(origin)

        realm = SingletonRealm(smtp.IMessageDelivery, RejectionDelivery())
        portal = Portal(realm, [AllowAnonymousAccess()])
        proto = smtp.SMTP()
        proto.portal = portal
        trans = StringTransport()
        proto.makeConnection(trans)

        # Deal with the necessary preliminaries
        proto.dataReceived('HELO example.com\r\n')
        trans.clear()

        # Try to specify our sender address
        proto.dataReceived('MAIL FROM:<*****@*****.**>\r\n')

        # Clean up the protocol before doing anything that might raise an
        # exception.
        proto.connectionLost(error.ConnectionLost())

        # Make sure that we received exactly the correct response
        self.assertEqual(
            trans.value(),
            '550 Cannot receive from specified address '
            '<*****@*****.**>: Sender not acceptable\r\n')
Пример #12
0
# hints for py2app
import Carbon.CF
import traceback

import cfsupport as cf

from twisted.python import log, threadable, failure
from twisted.internet import posixbase, error
from weakref import WeakKeyDictionary
from Foundation import NSRunLoop
from AppKit import NSApp

# cache two extremely common "failures" without traceback info
_faildict = {
    error.ConnectionDone: failure.Failure(error.ConnectionDone()),
    error.ConnectionLost: failure.Failure(error.ConnectionLost()),
}

class SelectableSocketWrapper(object):
    _objCache = WeakKeyDictionary()

    cf = None
    def socketWrapperForReactorAndObject(klass, reactor, obj):
        _objCache = klass._objCache
        if obj in _objCache:
            return _objCache[obj]
        v = _objCache[obj] = klass(reactor, obj)
        return v
    socketWrapperForReactorAndObject = classmethod(socketWrapperForReactorAndObject)
        
    def __init__(self, reactor, obj):
Пример #13
0
# -*- test-case-name: twisted.internet.test.test_main -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Backwards compatibility, and utility functions.

In general, this module should not be used, other than by reactor authors
who need to use the 'installReactor' method.
"""

from __future__ import division, absolute_import

from twisted.internet import error

CONNECTION_DONE = error.ConnectionDone('Connection done')
CONNECTION_LOST = error.ConnectionLost('Connection lost')


def installReactor(reactor):
    """
    Install reactor C{reactor}.

    @param reactor: An object that provides one or more IReactor* interfaces.
    """
    # this stuff should be common to all reactors.
    import twisted.internet
    import sys
    if 'twisted.internet.reactor' in sys.modules:
        raise error.ReactorAlreadyInstalledError("reactor already installed")
    twisted.internet.reactor = reactor
    sys.modules['twisted.internet.reactor'] = reactor
 def connectionLost(reason):
     """Catch disconnect and force a ConnectionLost."""
     orig_connectionLost(failure.Failure(txerror.ConnectionLost()))
     d.callback(None)
Пример #15
0
# -*- test-case-name: twisted.internet.test.test_main -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Backwards compatibility, and utility functions.

In general, this module should not be used, other than by reactor authors
who need to use the 'installReactor' method.
"""

from twisted.internet import error

CONNECTION_DONE = error.ConnectionDone("Connection done")
CONNECTION_LOST = error.ConnectionLost("Connection lost")


def installReactor(reactor):
    """
    Install reactor C{reactor}.

    @param reactor: An object that provides one or more IReactor* interfaces.
    """
    # this stuff should be common to all reactors.
    import sys

    import twisted.internet

    if "twisted.internet.reactor" in sys.modules:
        raise error.ReactorAlreadyInstalledError("reactor already installed")
    twisted.internet.reactor = reactor
    sys.modules["twisted.internet.reactor"] = reactor
Пример #16
0
 def connectionTimedOut(self):
     err = error.ConnectionLost("banana timeout: connection dropped")
     why = failure.Failure(err)
     self.shutdown(why)
Пример #17
0
 def lineLengthExceeded(self, line):
     """
     Called when the maximum line length has been reached.
     Override if it needs to be dealt with in some special way.
     """
     return error.ConnectionLost('Line length exceeded')
Пример #18
0
 def connectionLost(self):
     self.factory.callback(failure.Failure(error.ConnectionLost()))