Correct socket timeout for IMAP and POP3 connections

darcs-hash:20080725211945-86b55-0304eacb36aee0a5c2e6db43586ab6c75bfb419f.gz
This commit is contained in:
David Rousselie
2008-07-25 23:19:45 +02:00
parent 717e441733
commit 5cdb8e8ba6
2 changed files with 8 additions and 98 deletions

View File

@@ -44,104 +44,10 @@ from jcl.model import account
from jcl.model.account import Account, PresenceAccount from jcl.model.account import Account, PresenceAccount
from jmc.lang import Lang from jmc.lang import Lang
IMAP4_TIMEOUT = 10
POP3_TIMEOUT = 10
class NoAccountError(Exception): class NoAccountError(Exception):
"""Error raised when no corresponding account is found.""" """Error raised when no corresponding account is found."""
pass pass
## All MY* classes are implemented to add a timeout (settimeout)
## while connecting
class MYIMAP4(imaplib.IMAP4):
def open(self, host='', port=imaplib.IMAP4_PORT):
"""Setup connection to remote server on "host:port"
(default: localhost:standard IMAP4 port).
This connection will be used by the routines:
read, readline, send, shutdown.
"""
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(IMAP4_TIMEOUT)
self.sock.connect((host, port))
self.sock.settimeout(None)
self.file = self.sock.makefile('rb')
class MYIMAP4_SSL(imaplib.IMAP4_SSL):
def open(self, host='', port=imaplib.IMAP4_SSL_PORT):
"""Setup connection to remote server on "host:port".
(default: localhost:standard IMAP4 SSL port).
This connection will be used by the routines:
read, readline, send, shutdown.
"""
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.settimeout(IMAP4_TIMEOUT)
self.sock.connect((host, port))
self.sock.settimeout(None)
self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
class MYPOP3(poplib.POP3):
def __init__(self, host, port=poplib.POP3_PORT):
self.host = host
self.port = port
msg = "getaddrinfo returns an empty list"
self.sock = None
for res in socket.getaddrinfo(self.host,
self.port,
0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
self.sock.settimeout(POP3_TIMEOUT)
self.sock.connect(sa)
self.sock.settimeout(None)
except socket.error, msg:
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
self.file = self.sock.makefile('rb')
self._debugging = 0
self.welcome = self._getresp()
class MYPOP3_SSL(poplib.POP3_SSL):
def __init__(self, host, port=poplib.POP3_SSL_PORT, keyfile=None,
certfile=None):
self.host = host
self.port = port
self.keyfile = keyfile
self.certfile = certfile
self.buffer = ""
msg = "getaddrinfo returns an empty list"
self.sock = None
for res in socket.getaddrinfo(self.host, self.port, 0,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res
try:
self.sock = socket.socket(af, socktype, proto)
self.sock.settimeout(POP3_TIMEOUT)
self.sock.connect(sa)
self.sock.settimeout(None)
except socket.error, msg:
if self.sock:
self.sock.close()
self.sock = None
continue
break
if not self.sock:
raise socket.error, msg
self.file = self.sock.makefile('rb')
self.sslobj = socket.ssl(self.sock, self.keyfile, self.certfile)
self._debugging = 0
self.welcome = self._getresp()
def _get_default_status_msg(self, lang_class): def _get_default_status_msg(self, lang_class):
return self.get_type() + "://" + self.login + "@" + self.host + ":" + \ return self.get_type() + "://" + self.login + "@" + self.host + ":" + \
unicode(self.port) unicode(self.port)
@@ -408,9 +314,9 @@ class IMAPAccount(MailAccount):
+ " (" + self.mailbox + "). SSL=" + " (" + self.mailbox + "). SSL="
+ str(self.ssl)) + str(self.ssl))
if self.ssl: if self.ssl:
self.connection = MYIMAP4_SSL(self.host, self.port) self.connection = imaplib.IMAP4_SSL(self.host, self.port)
else: else:
self.connection = MYIMAP4(self.host, self.port) self.connection = imaplib.IMAP4(self.host, self.port)
self.connection.login(self.login, self.password) self.connection.login(self.login, self.password)
self.connected = True self.connected = True
@@ -582,9 +488,9 @@ class POP3Account(MailAccount):
+ self.login + "@" + self.host + ":" + + self.login + "@" + self.host + ":" +
str(self.port) + ". SSL=" + str(self.ssl)) str(self.port) + ". SSL=" + str(self.ssl))
if self.ssl: if self.ssl:
self.connection = MYPOP3_SSL(self.host, self.port) self.connection = poplib.POP3_SSL(self.host, self.port)
else: else:
self.connection = MYPOP3(self.host, self.port) self.connection = poplib.POP3(self.host, self.port)
try: try:
self.connection.apop(self.login, self.password) self.connection.apop(self.login, self.password)
except: except:

View File

@@ -20,6 +20,8 @@
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
## ##
import socket
from jcl.runner import JCLRunner from jcl.runner import JCLRunner
import jmc.model.account as account import jmc.model.account as account
@@ -81,6 +83,8 @@ class JMCRunner(JCLRunner):
self.db_url = "sqlite:///var/spool/jabber/jmc.db" self.db_url = "sqlite:///var/spool/jabber/jmc.db"
self.pid_file = "/var/run/jabber/jmc.pid" self.pid_file = "/var/run/jabber/jmc.pid"
self.config_file = "jmc.conf" self.config_file = "jmc.conf"
# set socket connection timeout (for IMAP and POP connections)
socket.setdefaulttimeout(10)
def setup_db(self): def setup_db(self):
JCLRunner.setup_db(self) JCLRunner.setup_db(self)