Last portion of doc-string and formatting refactoring
This commit is contained in:
parent
f084a1f78b
commit
4d904560a7
3 changed files with 159 additions and 116 deletions
|
@ -26,16 +26,26 @@ import unicodedata
|
||||||
from encodings import idna
|
from encodings import idna
|
||||||
|
|
||||||
class ILookupTable:
|
class ILookupTable:
|
||||||
""" Interface for character lookup classes. """
|
"""
|
||||||
|
Interface for character lookup classes
|
||||||
|
"""
|
||||||
|
|
||||||
def lookup(self, c):
|
def lookup(self, c):
|
||||||
""" Return whether character is in this table. """
|
"""
|
||||||
|
Return whether character is in this table
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
class IMappingTable:
|
class IMappingTable:
|
||||||
""" Interface for character mapping classes. """
|
"""
|
||||||
|
Interface for character mapping classes
|
||||||
|
"""
|
||||||
|
|
||||||
def map(self, c):
|
def map(self, c):
|
||||||
""" Return mapping for character. """
|
"""
|
||||||
|
Return mapping for character
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
class LookupTableFromFunction:
|
class LookupTableFromFunction:
|
||||||
|
|
||||||
|
@ -140,7 +150,8 @@ class Profile:
|
||||||
|
|
||||||
|
|
||||||
class NamePrep:
|
class NamePrep:
|
||||||
""" Implements preparation of internationalized domain names.
|
"""
|
||||||
|
Implements preparation of internationalized domain names
|
||||||
|
|
||||||
This class implements preparing internationalized domain names using the
|
This class implements preparing internationalized domain names using the
|
||||||
rules defined in RFC 3491, section 4 (Conversion operations).
|
rules defined in RFC 3491, section 4 (Conversion operations).
|
||||||
|
|
|
@ -54,11 +54,15 @@ def gattr(obj, attr, default=None):
|
||||||
|
|
||||||
|
|
||||||
class SSLWrapper:
|
class SSLWrapper:
|
||||||
'''
|
"""
|
||||||
Abstract SSLWrapper base class
|
Abstract SSLWrapper base class
|
||||||
'''
|
"""
|
||||||
|
|
||||||
class Error(IOError):
|
class Error(IOError):
|
||||||
''' Generic SSL Error Wrapper '''
|
"""
|
||||||
|
Generic SSL Error Wrapper
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, sock=None, exc=None, errno=None, strerror=None,
|
def __init__(self, sock=None, exc=None, errno=None, strerror=None,
|
||||||
peer=None):
|
peer=None):
|
||||||
self.parent = IOError
|
self.parent = IOError
|
||||||
|
@ -122,7 +126,7 @@ class SSLWrapper:
|
||||||
log.debug("%s.__init__ called with %s", self.__class__, sslobj)
|
log.debug("%s.__init__ called with %s", self.__class__, sslobj)
|
||||||
|
|
||||||
def recv(self, data, flags=None):
|
def recv(self, data, flags=None):
|
||||||
'''
|
"""
|
||||||
Receive wrapper for SSL object
|
Receive wrapper for SSL object
|
||||||
|
|
||||||
We can return None out of this function to signal that no data is
|
We can return None out of this function to signal that no data is
|
||||||
|
@ -130,16 +134,20 @@ class SSLWrapper:
|
||||||
depending on which SSL lib we're using. Unfortunately returning ''
|
depending on which SSL lib we're using. Unfortunately returning ''
|
||||||
can indicate that the socket has been closed, so to be sure, we avoid
|
can indicate that the socket has been closed, so to be sure, we avoid
|
||||||
this by returning None.
|
this by returning None.
|
||||||
'''
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def send(self, data, flags=None, now=False):
|
def send(self, data, flags=None, now=False):
|
||||||
''' Send wrapper for SSL object '''
|
"""
|
||||||
|
Send wrapper for SSL object
|
||||||
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
class PyOpenSSLWrapper(SSLWrapper):
|
class PyOpenSSLWrapper(SSLWrapper):
|
||||||
'''Wrapper class for PyOpenSSL's recv() and send() methods'''
|
"""
|
||||||
|
Wrapper class for PyOpenSSL's recv() and send() methods
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
self.parent = SSLWrapper
|
self.parent = SSLWrapper
|
||||||
|
@ -202,7 +210,9 @@ class PyOpenSSLWrapper(SSLWrapper):
|
||||||
|
|
||||||
|
|
||||||
class StdlibSSLWrapper(SSLWrapper):
|
class StdlibSSLWrapper(SSLWrapper):
|
||||||
'''Wrapper class for Python socket.ssl read() and write() methods'''
|
"""
|
||||||
|
Wrapper class for Python socket.ssl read() and write() methods
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, *args):
|
def __init__(self, *args):
|
||||||
self.parent = SSLWrapper
|
self.parent = SSLWrapper
|
||||||
|
@ -230,18 +240,18 @@ class StdlibSSLWrapper(SSLWrapper):
|
||||||
|
|
||||||
|
|
||||||
class NonBlockingTLS(PlugIn):
|
class NonBlockingTLS(PlugIn):
|
||||||
'''
|
"""
|
||||||
TLS connection used to encrypts already estabilished tcp connection.
|
TLS connection used to encrypts already estabilished tcp connection
|
||||||
|
|
||||||
Can be plugged into NonBlockingTCP and will make use of StdlibSSLWrapper or
|
Can be plugged into NonBlockingTCP and will make use of StdlibSSLWrapper or
|
||||||
PyOpenSSLWrapper.
|
PyOpenSSLWrapper.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, cacerts, mycerts):
|
def __init__(self, cacerts, mycerts):
|
||||||
'''
|
"""
|
||||||
:param cacerts: path to pem file with certificates of known XMPP servers
|
:param cacerts: path to pem file with certificates of known XMPP servers
|
||||||
:param mycerts: path to pem file with certificates of user trusted servers
|
:param mycerts: path to pem file with certificates of user trusted servers
|
||||||
'''
|
"""
|
||||||
PlugIn.__init__(self)
|
PlugIn.__init__(self)
|
||||||
self.cacerts = cacerts
|
self.cacerts = cacerts
|
||||||
self.mycerts = mycerts
|
self.mycerts = mycerts
|
||||||
|
@ -254,10 +264,10 @@ class NonBlockingTLS(PlugIn):
|
||||||
"SSL_CB_HANDSHAKE_START": 0x10, "SSL_CB_HANDSHAKE_DONE": 0x20}
|
"SSL_CB_HANDSHAKE_START": 0x10, "SSL_CB_HANDSHAKE_DONE": 0x20}
|
||||||
|
|
||||||
def plugin(self, owner):
|
def plugin(self, owner):
|
||||||
'''
|
"""
|
||||||
Use to PlugIn TLS into transport and start establishing immediately
|
Use to PlugIn TLS into transport and start establishing immediately.
|
||||||
Returns True if TLS/SSL was established correctly, otherwise False.
|
Returns True if TLS/SSL was established correctly, otherwise False
|
||||||
'''
|
"""
|
||||||
log.info('Starting TLS estabilishing')
|
log.info('Starting TLS estabilishing')
|
||||||
try:
|
try:
|
||||||
res = self._startSSL()
|
res = self._startSSL()
|
||||||
|
@ -289,7 +299,9 @@ class NonBlockingTLS(PlugIn):
|
||||||
"Unknown"), pkey.type())
|
"Unknown"), pkey.type())
|
||||||
|
|
||||||
def _startSSL(self):
|
def _startSSL(self):
|
||||||
''' Immediatedly switch socket to TLS mode. Used internally.'''
|
"""
|
||||||
|
Immediatedly switch socket to TLS mode. Used internally
|
||||||
|
"""
|
||||||
log.debug("_startSSL called")
|
log.debug("_startSSL called")
|
||||||
|
|
||||||
if USE_PYOPENSSL:
|
if USE_PYOPENSSL:
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
## GNU General Public License for more details.
|
## GNU General Public License for more details.
|
||||||
|
|
||||||
'''
|
"""
|
||||||
Transports are objects responsible for connecting to XMPP server and putting
|
Transports are objects responsible for connecting to XMPP server and putting
|
||||||
data to wrapped sockets in in desired form (SSL, TLS, TCP, for HTTP proxy,
|
data to wrapped sockets in in desired form (SSL, TLS, TCP, for HTTP proxy,
|
||||||
for SOCKS5 proxy...)
|
for SOCKS5 proxy...)
|
||||||
|
|
||||||
Transports are not aware of XMPP stanzas and only responsible for low-level
|
Transports are not aware of XMPP stanzas and only responsible for low-level
|
||||||
connection handling.
|
connection handling.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
from simplexml import ustr
|
from simplexml import ustr
|
||||||
from plugin import PlugIn
|
from plugin import PlugIn
|
||||||
|
@ -41,12 +41,12 @@ import logging
|
||||||
log = logging.getLogger('gajim.c.x.transports_nb')
|
log = logging.getLogger('gajim.c.x.transports_nb')
|
||||||
|
|
||||||
def urisplit(uri):
|
def urisplit(uri):
|
||||||
'''
|
"""
|
||||||
Function for splitting URI string to tuple (protocol, host, port, path).
|
Function for splitting URI string to tuple (protocol, host, port, path).
|
||||||
e.g. urisplit('http://httpcm.jabber.org:123/webclient') returns
|
e.g. urisplit('http://httpcm.jabber.org:123/webclient') returns ('http',
|
||||||
('http', 'httpcm.jabber.org', 123, '/webclient')
|
'httpcm.jabber.org', 123, '/webclient') return 443 as default port if proto
|
||||||
return 443 as default port if proto is https else 80
|
is https else 80
|
||||||
'''
|
"""
|
||||||
splitted = urlparse.urlsplit(uri)
|
splitted = urlparse.urlsplit(uri)
|
||||||
proto, host, path = splitted.scheme, splitted.hostname, splitted.path
|
proto, host, path = splitted.scheme, splitted.hostname, splitted.path
|
||||||
try:
|
try:
|
||||||
|
@ -102,17 +102,18 @@ CONNECTED = 'CONNECTED'
|
||||||
STATES = (DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING)
|
STATES = (DISCONNECTED, CONNECTING, PROXY_CONNECTING, CONNECTED, DISCONNECTING)
|
||||||
|
|
||||||
class NonBlockingTransport(PlugIn):
|
class NonBlockingTransport(PlugIn):
|
||||||
'''
|
"""
|
||||||
Abstract class representing a transport.
|
Abstract class representing a transport
|
||||||
|
|
||||||
Subclasses CAN have different constructor signature but connect method SHOULD
|
Subclasses CAN have different constructor signature but connect method SHOULD
|
||||||
be the same.
|
be the same.
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
||||||
certs):
|
certs):
|
||||||
'''
|
"""
|
||||||
Each trasport class can have different constructor but it has to have at
|
Each trasport class can have different constructor but it has to have at
|
||||||
least all the arguments of NonBlockingTransport constructor.
|
least all the arguments of NonBlockingTransport constructor
|
||||||
|
|
||||||
:param raise_event: callback for monitoring of sent and received data
|
:param raise_event: callback for monitoring of sent and received data
|
||||||
:param on_disconnect: callback called on disconnection during runtime
|
:param on_disconnect: callback called on disconnection during runtime
|
||||||
|
@ -121,7 +122,7 @@ class NonBlockingTransport(PlugIn):
|
||||||
TCP connection is done
|
TCP connection is done
|
||||||
:param certs: tuple of (cacerts, mycerts) see constructor of
|
:param certs: tuple of (cacerts, mycerts) see constructor of
|
||||||
tls_nb.NonBlockingTLS for more details
|
tls_nb.NonBlockingTLS for more details
|
||||||
'''
|
"""
|
||||||
PlugIn.__init__(self)
|
PlugIn.__init__(self)
|
||||||
self.raise_event = raise_event
|
self.raise_event = raise_event
|
||||||
self.on_disconnect = on_disconnect
|
self.on_disconnect = on_disconnect
|
||||||
|
@ -157,14 +158,14 @@ class NonBlockingTransport(PlugIn):
|
||||||
self.disconnect(do_callback=False)
|
self.disconnect(do_callback=False)
|
||||||
|
|
||||||
def connect(self, conn_5tuple, on_connect, on_connect_failure):
|
def connect(self, conn_5tuple, on_connect, on_connect_failure):
|
||||||
'''
|
"""
|
||||||
Creates and connects transport to server and port defined in conn_5tuple
|
Creates and connects transport to server and port defined in conn_5tuple
|
||||||
which should be item from list returned from getaddrinfo.
|
which should be item from list returned from getaddrinfo
|
||||||
|
|
||||||
:param conn_5tuple: 5-tuple returned from getaddrinfo
|
:param conn_5tuple: 5-tuple returned from getaddrinfo
|
||||||
:param on_connect: callback called on successful connect to the server
|
:param on_connect: callback called on successful connect to the server
|
||||||
:param on_connect_failure: callback called on failure when connecting
|
:param on_connect_failure: callback called on failure when connecting
|
||||||
'''
|
"""
|
||||||
self.on_connect = on_connect
|
self.on_connect = on_connect
|
||||||
self.on_connect_failure = on_connect_failure
|
self.on_connect_failure = on_connect_failure
|
||||||
self.server, self.port = conn_5tuple[4][:2]
|
self.server, self.port = conn_5tuple[4][:2]
|
||||||
|
@ -178,14 +179,18 @@ class NonBlockingTransport(PlugIn):
|
||||||
return self.state
|
return self.state
|
||||||
|
|
||||||
def _on_connect(self):
|
def _on_connect(self):
|
||||||
''' preceeds call of on_connect callback '''
|
"""
|
||||||
|
Preceeds call of on_connect callback
|
||||||
|
"""
|
||||||
# data is reference to socket wrapper instance. We don't need it in client
|
# data is reference to socket wrapper instance. We don't need it in client
|
||||||
# because
|
# because
|
||||||
self.set_state(CONNECTED)
|
self.set_state(CONNECTED)
|
||||||
self.on_connect()
|
self.on_connect()
|
||||||
|
|
||||||
def _on_connect_failure(self, err_message):
|
def _on_connect_failure(self, err_message):
|
||||||
''' preceeds call of on_connect_failure callback '''
|
"""
|
||||||
|
Preceeds call of on_connect_failure callback
|
||||||
|
"""
|
||||||
# In case of error while connecting we need to disconnect transport
|
# In case of error while connecting we need to disconnect transport
|
||||||
# but we don't want to call DisconnectHandlers from client,
|
# but we don't want to call DisconnectHandlers from client,
|
||||||
# thus the do_callback=False
|
# thus the do_callback=False
|
||||||
|
@ -204,15 +209,16 @@ class NonBlockingTransport(PlugIn):
|
||||||
self.on_disconnect()
|
self.on_disconnect()
|
||||||
|
|
||||||
def onreceive(self, recv_handler):
|
def onreceive(self, recv_handler):
|
||||||
'''
|
"""
|
||||||
Sets the on_receive callback.
|
Set the on_receive callback.
|
||||||
|
|
||||||
onreceive(None) sets callback to Dispatcher.ProcessNonBlocking which is
|
onreceive(None) sets callback to Dispatcher.ProcessNonBlocking which is
|
||||||
the default one that will decide what to do with received stanza based on
|
the default one that will decide what to do with received stanza based on
|
||||||
its tag name and namespace.
|
its tag name and namespace.
|
||||||
|
|
||||||
Do not confuse it with on_receive() method, which is the callback itself.
|
Do not confuse it with on_receive() method, which is the callback
|
||||||
'''
|
itself.
|
||||||
|
"""
|
||||||
if not recv_handler:
|
if not recv_handler:
|
||||||
if hasattr(self, '_owner') and hasattr(self._owner, 'Dispatcher'):
|
if hasattr(self, '_owner') and hasattr(self._owner, 'Dispatcher'):
|
||||||
self.on_receive = self._owner.Dispatcher.ProcessNonBlocking
|
self.on_receive = self._owner.Dispatcher.ProcessNonBlocking
|
||||||
|
@ -226,13 +232,17 @@ class NonBlockingTransport(PlugIn):
|
||||||
self.set_state(CONNECTING)
|
self.set_state(CONNECTING)
|
||||||
|
|
||||||
def read_timeout(self):
|
def read_timeout(self):
|
||||||
''' called when there's no response from server in defined timeout '''
|
"""
|
||||||
|
Called when there's no response from server in defined timeout
|
||||||
|
"""
|
||||||
if self.on_timeout:
|
if self.on_timeout:
|
||||||
self.on_timeout()
|
self.on_timeout()
|
||||||
self.renew_send_timeout()
|
self.renew_send_timeout()
|
||||||
|
|
||||||
def read_timeout2(self):
|
def read_timeout2(self):
|
||||||
''' called when there's no response from server in defined timeout '''
|
"""
|
||||||
|
called when there's no response from server in defined timeout
|
||||||
|
"""
|
||||||
if self.on_timeout2:
|
if self.on_timeout2:
|
||||||
self.on_timeout2()
|
self.on_timeout2()
|
||||||
self.renew_send_timeout2()
|
self.renew_send_timeout2()
|
||||||
|
@ -277,17 +287,17 @@ class NonBlockingTransport(PlugIn):
|
||||||
|
|
||||||
|
|
||||||
class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
'''
|
"""
|
||||||
Non-blocking TCP socket wrapper.
|
Non-blocking TCP socket wrapper
|
||||||
|
|
||||||
It is used for simple XMPP connection. Can be connected via proxy and can
|
It is used for simple XMPP connection. Can be connected via proxy and can
|
||||||
estabilish TLS connection.
|
estabilish TLS connection.
|
||||||
'''
|
"""
|
||||||
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
||||||
certs, proxy_dict=None):
|
certs, proxy_dict=None):
|
||||||
'''
|
"""
|
||||||
:param proxy_dict: dictionary with proxy data as loaded from config file
|
:param proxy_dict: dictionary with proxy data as loaded from config file
|
||||||
'''
|
"""
|
||||||
NonBlockingTransport.__init__(self, raise_event, on_disconnect, idlequeue,
|
NonBlockingTransport.__init__(self, raise_event, on_disconnect, idlequeue,
|
||||||
estabilish_tls, certs)
|
estabilish_tls, certs)
|
||||||
IdleObject.__init__(self)
|
IdleObject.__init__(self)
|
||||||
|
@ -371,10 +381,10 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
proxy_creds=self.proxy_dict['credentials'])
|
proxy_creds=self.proxy_dict['credentials'])
|
||||||
|
|
||||||
def _on_connect(self):
|
def _on_connect(self):
|
||||||
'''
|
"""
|
||||||
Preceeds invoking of on_connect callback. TCP connection is already
|
Preceed invoking of on_connect callback. TCP connection is already
|
||||||
estabilished by this time.
|
estabilished by this time
|
||||||
'''
|
"""
|
||||||
if self.estabilish_tls:
|
if self.estabilish_tls:
|
||||||
self.tls_init(
|
self.tls_init(
|
||||||
on_succ = lambda: NonBlockingTransport._on_connect(self),
|
on_succ = lambda: NonBlockingTransport._on_connect(self),
|
||||||
|
@ -384,10 +394,10 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
NonBlockingTransport._on_connect(self)
|
NonBlockingTransport._on_connect(self)
|
||||||
|
|
||||||
def tls_init(self, on_succ, on_fail):
|
def tls_init(self, on_succ, on_fail):
|
||||||
'''
|
"""
|
||||||
Estabilishes TLS/SSL using this TCP connection by plugging a
|
Estabilishes TLS/SSL using this TCP connection by plugging a
|
||||||
NonBlockingTLS module
|
NonBlockingTLS module
|
||||||
'''
|
"""
|
||||||
cacerts, mycerts = self.certs
|
cacerts, mycerts = self.certs
|
||||||
result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self)
|
result = tls_nb.NonBlockingTLS.get_instance(cacerts, mycerts).PlugIn(self)
|
||||||
if result:
|
if result:
|
||||||
|
@ -396,12 +406,16 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
on_fail()
|
on_fail()
|
||||||
|
|
||||||
def pollin(self):
|
def pollin(self):
|
||||||
'''called by idlequeu when receive on plugged socket is possible '''
|
"""
|
||||||
|
Called by idlequeu when receive on plugged socket is possible
|
||||||
|
"""
|
||||||
log.info('pollin called, state == %s' % self.get_state())
|
log.info('pollin called, state == %s' % self.get_state())
|
||||||
self._do_receive()
|
self._do_receive()
|
||||||
|
|
||||||
def pollout(self):
|
def pollout(self):
|
||||||
'''called by idlequeu when send to plugged socket is possible'''
|
"""
|
||||||
|
Called by idlequeu when send to plugged socket is possible
|
||||||
|
"""
|
||||||
log.info('pollout called, state == %s' % self.get_state())
|
log.info('pollout called, state == %s' % self.get_state())
|
||||||
|
|
||||||
if self.get_state() == CONNECTING:
|
if self.get_state() == CONNECTING:
|
||||||
|
@ -417,7 +431,9 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
self._do_send()
|
self._do_send()
|
||||||
|
|
||||||
def pollend(self):
|
def pollend(self):
|
||||||
'''called by idlequeue on TCP connection errors'''
|
"""
|
||||||
|
Called by idlequeue on TCP connection errors
|
||||||
|
"""
|
||||||
log.info('pollend called, state == %s' % self.get_state())
|
log.info('pollend called, state == %s' % self.get_state())
|
||||||
|
|
||||||
if self.get_state() == CONNECTING:
|
if self.get_state() == CONNECTING:
|
||||||
|
@ -465,10 +481,10 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
log.warn('remove_timeout: no self.fd state is %s' % self.get_state())
|
log.warn('remove_timeout: no self.fd state is %s' % self.get_state())
|
||||||
|
|
||||||
def send(self, raw_data, now=False):
|
def send(self, raw_data, now=False):
|
||||||
'''
|
"""
|
||||||
Append raw_data to the queue of messages to be send.
|
Append raw_data to the queue of messages to be send. If supplied data is
|
||||||
If supplied data is unicode string, encode it to utf-8.
|
unicode string, encode it to utf-8.
|
||||||
'''
|
"""
|
||||||
NonBlockingTransport.send(self, raw_data, now)
|
NonBlockingTransport.send(self, raw_data, now)
|
||||||
|
|
||||||
r = self.encode_stanza(raw_data)
|
r = self.encode_stanza(raw_data)
|
||||||
|
@ -482,7 +498,9 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
self._plug_idle(writable=True, readable=True)
|
self._plug_idle(writable=True, readable=True)
|
||||||
|
|
||||||
def encode_stanza(self, stanza):
|
def encode_stanza(self, stanza):
|
||||||
''' Encode str or unicode to utf-8 '''
|
"""
|
||||||
|
Encode str or unicode to utf-8
|
||||||
|
"""
|
||||||
if isinstance(stanza, unicode):
|
if isinstance(stanza, unicode):
|
||||||
stanza = stanza.encode('utf-8')
|
stanza = stanza.encode('utf-8')
|
||||||
elif not isinstance(stanza, str):
|
elif not isinstance(stanza, str):
|
||||||
|
@ -490,8 +508,8 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
return stanza
|
return stanza
|
||||||
|
|
||||||
def _plug_idle(self, writable, readable):
|
def _plug_idle(self, writable, readable):
|
||||||
'''
|
"""
|
||||||
Plugs file descriptor of socket to Idlequeue.
|
Plug file descriptor of socket to Idlequeue
|
||||||
|
|
||||||
Plugged socket will be watched for "send possible" or/and "recv possible"
|
Plugged socket will be watched for "send possible" or/and "recv possible"
|
||||||
events. pollin() callback is invoked on "recv possible", pollout() on
|
events. pollin() callback is invoked on "recv possible", pollout() on
|
||||||
|
@ -499,15 +517,15 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
|
|
||||||
Plugged socket will always be watched for "error" event - in that case,
|
Plugged socket will always be watched for "error" event - in that case,
|
||||||
pollend() is called.
|
pollend() is called.
|
||||||
'''
|
"""
|
||||||
log.info('Plugging fd %d, W:%s, R:%s' % (self.fd, writable, readable))
|
log.info('Plugging fd %d, W:%s, R:%s' % (self.fd, writable, readable))
|
||||||
self.idlequeue.plug_idle(self, writable, readable)
|
self.idlequeue.plug_idle(self, writable, readable)
|
||||||
|
|
||||||
def _do_send(self):
|
def _do_send(self):
|
||||||
'''
|
"""
|
||||||
Called when send() to connected socket is possible. First message from
|
Called when send() to connected socket is possible. First message from
|
||||||
sendqueue will be sent.
|
sendqueue will be sent
|
||||||
'''
|
"""
|
||||||
if not self.sendbuff:
|
if not self.sendbuff:
|
||||||
if not self.sendqueue:
|
if not self.sendqueue:
|
||||||
log.warn('calling send on empty buffer and queue')
|
log.warn('calling send on empty buffer and queue')
|
||||||
|
@ -530,10 +548,10 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
def _do_receive(self):
|
def _do_receive(self):
|
||||||
'''
|
"""
|
||||||
Reads all pending incoming data. Will call owner's disconnected() method
|
Reads all pending incoming data. Will call owner's disconnected() method
|
||||||
if appropriate.
|
if appropriate
|
||||||
'''
|
"""
|
||||||
received = None
|
received = None
|
||||||
errnum = 0
|
errnum = 0
|
||||||
errstr = 'No Error Set'
|
errstr = 'No Error Set'
|
||||||
|
@ -588,27 +606,29 @@ class NonBlockingTCP(NonBlockingTransport, IdleObject):
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
def _on_receive(self, data):
|
def _on_receive(self, data):
|
||||||
''' preceeds on_receive callback. It peels off and checks HTTP headers in
|
"""
|
||||||
HTTP classes, in here it just calls the callback.'''
|
Preceeds on_receive callback. It peels off and checks HTTP headers in
|
||||||
|
HTTP classes, in here it just calls the callback
|
||||||
|
"""
|
||||||
self.on_receive(data)
|
self.on_receive(data)
|
||||||
|
|
||||||
|
|
||||||
class NonBlockingHTTP(NonBlockingTCP):
|
class NonBlockingHTTP(NonBlockingTCP):
|
||||||
'''
|
"""
|
||||||
Socket wrapper that creates HTTP message out of sent data and peels-off
|
Socket wrapper that creates HTTP message out of sent data and peels-off HTTP
|
||||||
HTTP headers from incoming messages.
|
headers from incoming messages
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
def __init__(self, raise_event, on_disconnect, idlequeue, estabilish_tls,
|
||||||
certs, on_http_request_possible, on_persistent_fallback, http_dict,
|
certs, on_http_request_possible, on_persistent_fallback, http_dict,
|
||||||
proxy_dict=None):
|
proxy_dict=None):
|
||||||
'''
|
"""
|
||||||
:param on_http_request_possible: method to call when HTTP request to
|
:param on_http_request_possible: method to call when HTTP request to
|
||||||
socket owned by transport is possible.
|
socket owned by transport is possible.
|
||||||
:param on_persistent_fallback: callback called when server ends TCP
|
:param on_persistent_fallback: callback called when server ends TCP
|
||||||
connection. It doesn't have to be fatal for HTTP session.
|
connection. It doesn't have to be fatal for HTTP session.
|
||||||
:param http_dict: dictionary with data for HTTP request and headers
|
:param http_dict: dictionary with data for HTTP request and headers
|
||||||
'''
|
"""
|
||||||
NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue,
|
NonBlockingTCP.__init__(self, raise_event, on_disconnect, idlequeue,
|
||||||
estabilish_tls, certs, proxy_dict)
|
estabilish_tls, certs, proxy_dict)
|
||||||
|
|
||||||
|
@ -639,10 +659,10 @@ class NonBlockingHTTP(NonBlockingTCP):
|
||||||
self.send(self.build_http_message(raw_data), now)
|
self.send(self.build_http_message(raw_data), now)
|
||||||
|
|
||||||
def _on_receive(self, data):
|
def _on_receive(self, data):
|
||||||
'''
|
"""
|
||||||
Preceeds passing received data to owner class. Gets rid of HTTP headers
|
Preceeds passing received data to owner class. Gets rid of HTTP headers
|
||||||
and checks them.
|
and checks them.
|
||||||
'''
|
"""
|
||||||
if self.get_state() == PROXY_CONNECTING:
|
if self.get_state() == PROXY_CONNECTING:
|
||||||
NonBlockingTCP._on_receive(self, data)
|
NonBlockingTCP._on_receive(self, data)
|
||||||
return
|
return
|
||||||
|
@ -686,10 +706,10 @@ class NonBlockingHTTP(NonBlockingTCP):
|
||||||
self.on_http_request_possible()
|
self.on_http_request_possible()
|
||||||
|
|
||||||
def build_http_message(self, httpbody, method='POST'):
|
def build_http_message(self, httpbody, method='POST'):
|
||||||
'''
|
"""
|
||||||
Builds http message with given body.
|
Builds http message with given body. Values for headers and status line
|
||||||
Values for headers and status line fields are taken from class variables.
|
fields are taken from class variables
|
||||||
'''
|
"""
|
||||||
absolute_uri = '%s://%s:%s%s' % (self.http_protocol, self.http_host,
|
absolute_uri = '%s://%s:%s%s' % (self.http_protocol, self.http_host,
|
||||||
self.http_port, self.http_path)
|
self.http_port, self.http_path)
|
||||||
headers = ['%s %s %s' % (method, absolute_uri, self.http_version),
|
headers = ['%s %s %s' % (method, absolute_uri, self.http_version),
|
||||||
|
@ -711,14 +731,14 @@ class NonBlockingHTTP(NonBlockingTCP):
|
||||||
return('%s%s' % (headers, httpbody))
|
return('%s%s' % (headers, httpbody))
|
||||||
|
|
||||||
def parse_http_message(self, message):
|
def parse_http_message(self, message):
|
||||||
'''
|
"""
|
||||||
splits http message to tuple:
|
Split http message into a tuple:
|
||||||
(statusline - list of e.g. ['HTTP/1.1', '200', 'OK'],
|
(statusline - list of e.g. ['HTTP/1.1', '200', 'OK'],
|
||||||
headers - dictionary of headers e.g. {'Content-Length': '604',
|
headers - dictionary of headers e.g. {'Content-Length': '604',
|
||||||
'Content-Type': 'text/xml; charset=utf-8'},
|
'Content-Type': 'text/xml; charset=utf-8'},
|
||||||
httpbody - string with http body)
|
httpbody - string with http body)
|
||||||
http_rest - what is left in the message after a full HTTP header + body
|
http_rest - what is left in the message after a full HTTP header + body
|
||||||
'''
|
"""
|
||||||
message = message.replace('\r','')
|
message = message.replace('\r','')
|
||||||
message = message.lstrip('\n')
|
message = message.lstrip('\n')
|
||||||
splitted = message.split('\n\n')
|
splitted = message.split('\n\n')
|
||||||
|
@ -745,10 +765,10 @@ class NonBlockingHTTP(NonBlockingTCP):
|
||||||
|
|
||||||
|
|
||||||
class NonBlockingHTTPBOSH(NonBlockingHTTP):
|
class NonBlockingHTTPBOSH(NonBlockingHTTP):
|
||||||
'''
|
"""
|
||||||
Class for BOSH HTTP connections. Slightly redefines HTTP transport by calling
|
Class for BOSH HTTP connections. Slightly redefines HTTP transport by
|
||||||
bosh bodytag generating callback before putting data on wire.
|
calling bosh bodytag generating callback before putting data on wire
|
||||||
'''
|
"""
|
||||||
|
|
||||||
def set_stanza_build_cb(self, build_cb):
|
def set_stanza_build_cb(self, build_cb):
|
||||||
self.build_cb = build_cb
|
self.build_cb = build_cb
|
||||||
|
|
Loading…
Add table
Reference in a new issue