smtplib timeout

S

Stuart D. Gathman

I am doing SMTP callbacks in a Python milter
(http://pymilter.sourceforge.net) using the smtplib module. For some
spammer MXes, it takes days (!) before smtplib.sendmail will return.
Since the spammer connects to us every few seconds, this quickly leads to
a problem :)

I need to set a timelimit for the operation of
smtplib.sendmail. It has to be thread based, because pymilter uses
libmilter which is thread based. There are some cookbook recipies which
run a function in a new thread and call Thread.join(timeout). This
doesn't help, because although the calling thread gets a nice timeout
exception, the thread running the function continues to run. In fact, the
problem is worse, because even more threads are created.
 
A

Alan Kennedy

[Stuart D. Gathman]
I need to set a timelimit for the operation of
smtplib.sendmail. It has to be thread based, because pymilter uses
libmilter which is thread based. There are some cookbook recipies which
run a function in a new thread and call Thread.join(timeout). This
doesn't help, because although the calling thread gets a nice timeout
exception, the thread running the function continues to run. In fact, the
problem is worse, because even more threads are created.

Have you tried setting a default socket timeout, which applies to all
socket operations?

Here is a code snippet which times out for server connections. Timeouts
should also work for sending and receiving on sockets that are already
open, i.e. should work for the smtplib.sendmail call.

==============================
import socket
import smtplib

dud_server = '192.168.1.1'
timeout_value = 1.0 # seconds

socket.setdefaulttimeout(timeout_value)

print "connecting to server: %s" % dud_server
try:
connection = smtplib.SMTP(dud_server)
except socket.timeout:
print "server timed out"
==============================

HTH,
 
S

Stuart D. Gathman

[Stuart D. Gathman]
I need to set a timelimit for the operation of
smtplib.sendmail. It has to be thread based, because pymilter uses
libmilter which is thread based.

Have you tried setting a default socket timeout, which applies to all
socket operations?

Does this apply to all threads, is it inherited when creating threads, or
does each thread need to specify it separately?
 
A

Alan Kennedy

[Stuart D. Gathman]
[Alan Kennedy]
[Stuart D. Gathman]
Does this apply to all threads, is it inherited when creating threads, or
does each thread need to specify it separately?

It is a module level default, which affects all socket operations after
the socket.setdefaulttimeout() call, regardless of whether they are in
threads or not.

So you only need to call it once, probably before any other processing
takes place.

=================================================
import socket
import smtplib
import threading

dud_server = '192.168.1.1'
timeout_value = 1.0 # seconds

socket.setdefaulttimeout(timeout_value)

def do_connect(tno):
print "Thread%d: connecting to server: %s" % (tno, dud_server)
try:
connection = smtplib.SMTP(dud_server)
except socket.timeout:
print "Thread%d: server timed out" % tno

for x in range(5):
t = threading.Thread(target=do_connect, args=(x,))
t.start()
=================================================

C:\>python smtp_timeout.py

Thread0: connecting to server: 192.168.1.1
Thread1: connecting to server: 192.168.1.1
Thread2: connecting to server: 192.168.1.1
Thread3: connecting to server: 192.168.1.1
Thread4: connecting to server: 192.168.1.1
Thread0: server timed out
Thread1: server timed out
Thread2: server timed out
Thread4: server timed out
Thread3: server timed out
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,610
Members
45,259
Latest member
JorjaBurne

Latest Threads

Top