bytes optimization

This commit is contained in:
Stuart D. Gathman
2020-06-18 16:40:54 -04:00
parent 4c7c76fca4
commit 879e65bc31
4 changed files with 24 additions and 16 deletions
+5 -2
View File
@@ -181,12 +181,12 @@ def noreply(func):
wrapper.milter_protocol = nr_mask wrapper.milter_protocol = nr_mask
return wrapper return wrapper
## Function decorator to set encoding error strategy. ## Function decorator to set decoding error strategy.
# Current RFCs define UTF-8 as the standard encoding for SMTP # Current RFCs define UTF-8 as the standard encoding for SMTP
# envelope and header fields. By default, Milter.Base decodes # envelope and header fields. By default, Milter.Base decodes
# envelope and header values with errors='surrogateescape'. # envelope and header values with errors='surrogateescape'.
# This decorator can change the error strategy to, e.g., 'ignore' or 'replace'. # This decorator can change the error strategy to, e.g., 'ignore' or 'replace'.
def encodingerror(strategy): def decode(strategy):
def setstrategy(func): def setstrategy(func):
func.error_strategy = strategy func.error_strategy = strategy
return func return func
@@ -391,6 +391,9 @@ class Base(object):
def header_bytes(self,fld,val): def header_bytes(self,fld,val):
try: try:
e = getattr(self.header,'error_strategy','surrogateescape') e = getattr(self.header,'error_strategy','surrogateescape')
if e == 'bytes':
self.header_bytes = self.header
return self.header(fld,val)
s = val.decode(encoding='utf-8',errors=e) s = val.decode(encoding='utf-8',errors=e)
except UnicodeDecodeError: s = val except UnicodeDecodeError: s = val
return self.header(fld,s) return self.header(fld,s)
+1 -1
View File
@@ -183,7 +183,7 @@ class TestBase(object):
if rc != Milter.CONTINUE: return rc if rc != Milter.CONTINUE: return rc
# header # header
for h,val in msg.items(): for h,val in msg.items():
rc = self.header(h,val) rc = self.header_bytes(h,val.encode())
if rc != Milter.CONTINUE: return rc if rc != Milter.CONTINUE: return rc
# eoh # eoh
self._stage = Milter.M_EOH self._stage = Milter.M_EOH
+8 -8
View File
@@ -67,7 +67,7 @@ class sampleMilter(Milter.Milter):
self.log("rcpt to",to,str) self.log("rcpt to",to,str)
return Milter.CONTINUE return Milter.CONTINUE
@Milter.encodingerror('replace') @Milter.decode('bytes')
def header(self,name,val): def header(self,name,val):
lname = name.lower() lname = name.lower()
if lname == 'subject': if lname == 'subject':
@@ -76,22 +76,22 @@ class sampleMilter(Milter.Milter):
# (delete if you read chinese mail) # (delete if you read chinese mail)
#print('val=',val.encode(errors='surrogateescape')) #print('val=',val.encode(errors='surrogateescape'))
print('val=',val) print('val=',val)
if val.startswith('=?big5') or val.startswith('=?ISO-2022-JP'): if val.startswith(b'=?big5') or val.startswith(b'=?ISO-2022-JP'):
self.log('REJECT: %s: %s' % (name,val)) self.log('REJECT: %s: %s' % (name,val))
#self.setreply('550','','Go away spammer') #self.setreply('550','','Go away spammer')
return Milter.REJECT return Milter.REJECT
# check for common spam keywords # check for common spam keywords
if val.find("$$$") >= 0 or val.find("XXX") >= 0 \ if val.find(b"$$$") >= 0 or val.find(b"XXX") >= 0 \
or val.find("!!!") >= 0 or val.find("FREE") >= 0: or val.find(b"!!!") >= 0 or val.find(b"FREE") >= 0:
self.log('REJECT: %s: %s' % (name,val)) self.log('REJECT: %s: %s' % (name,val))
#self.setreply('550','','Go away spammer') #self.setreply('550','','Go away spammer')
return Milter.REJECT return Milter.REJECT
# check for spam that pretends to be legal # check for spam that pretends to be legal
lval = val.lower() lval = val.lower()
if lval.startswith("adv:") or lval.startswith("adv.") \ if lval.startswith(b"adv:") or lval.startswith(b"adv.") \
or lval.find('viagra') >= 0: or lval.find(b'viagra') >= 0:
self.log('REJECT: %s: %s' % (name,val)) self.log('REJECT: %s: %s' % (name,val))
return Milter.REJECT return Milter.REJECT
@@ -103,7 +103,7 @@ class sampleMilter(Milter.Milter):
# check for common bulk mailers # check for common bulk mailers
if lname == 'x-mailer' and \ if lname == 'x-mailer' and \
val.lower() in ('direct email','calypso','mail bomber'): val.lower() in (b'direct email',b'calypso',b'mail bomber'):
self.log('REJECT: %s: %s' % (name,val)) self.log('REJECT: %s: %s' % (name,val))
#self.setreply('550','','Go away spammer') #self.setreply('550','','Go away spammer')
return Milter.REJECT return Milter.REJECT
@@ -112,7 +112,7 @@ class sampleMilter(Milter.Milter):
if lname in ('subject','x-mailer'): if lname in ('subject','x-mailer'):
self.log('%s: %s' % (name,val)) self.log('%s: %s' % (name,val))
if self.fp: if self.fp:
self.fp.write(("%s: %s\n" % (name,val)).encode(errors='surrogateescape')) # add header to buffer self.fp.write(b"%s: %s\n" % (name.encode(),val)) # add header to buffer
return Milter.CONTINUE return Milter.CONTINUE
def eoh(self): def eoh(self):
+10 -5
View File
@@ -74,7 +74,8 @@ class BMSMilterTestCase(unittest.TestCase):
self.assertTrue(rc == Milter.ACCEPT) self.assertTrue(rc == Milter.ACCEPT)
self.assertTrue(ctx._bodyreplaced,"Message body not replaced") self.assertTrue(ctx._bodyreplaced,"Message body not replaced")
fp = ctx._body fp = ctx._body
open('test/'+fname+".tstout","wb").write(fp.getvalue()) with open('test/'+fname+".tstout","wb") as f:
f.write(fp.getvalue())
#self.assertTrue(fp.getvalue() == open("test/virus1.out","r").read()) #self.assertTrue(fp.getvalue() == open("test/virus1.out","r").read())
fp.seek(0) fp.seek(0)
msg = mime.message_from_file(fp) msg = mime.message_from_file(fp)
@@ -97,7 +98,8 @@ class BMSMilterTestCase(unittest.TestCase):
self.assertTrue(rc == Milter.ACCEPT) self.assertTrue(rc == Milter.ACCEPT)
self.assertTrue(milter._bodyreplaced,"Message body not replaced") self.assertTrue(milter._bodyreplaced,"Message body not replaced")
fp = milter._body fp = milter._body
open('test/'+fname+".tstout","wb").write(fp.getvalue()) with open('test/'+fname+".tstout","wb") as f:
f.write(fp.getvalue())
#self.assertTrue(fp.getvalue() == open("test/virus1.out","r").read()) #self.assertTrue(fp.getvalue() == open("test/virus1.out","r").read())
fp.seek(0) fp.seek(0)
msg = mime.message_from_file(fp) msg = mime.message_from_file(fp)
@@ -112,7 +114,8 @@ class BMSMilterTestCase(unittest.TestCase):
self.assertTrue(rc == Milter.ACCEPT) self.assertTrue(rc == Milter.ACCEPT)
self.assertFalse(milter._bodyreplaced,"Milter needlessly replaced body.") self.assertFalse(milter._bodyreplaced,"Milter needlessly replaced body.")
fp = milter._body fp = milter._body
open('test/'+fname+".tstout","wb").write(fp.getvalue()) with open('test/'+fname+".tstout","wb") as f:
f.write(fp.getvalue())
milter.close() milter.close()
def testDefang2(self): def testDefang2(self):
@@ -126,7 +129,8 @@ class BMSMilterTestCase(unittest.TestCase):
self.assertTrue(rc == Milter.ACCEPT) self.assertTrue(rc == Milter.ACCEPT)
self.assertTrue(milter._bodyreplaced,"Message body not replaced") self.assertTrue(milter._bodyreplaced,"Message body not replaced")
fp = milter._body fp = milter._body
open("test/virus3.tstout","wb").write(fp.getvalue()) with open("test/virus3.tstout","wb") as f:
f.write(fp.getvalue())
#self.assertTrue(fp.getvalue() == open("test/virus3.out","r").read()) #self.assertTrue(fp.getvalue() == open("test/virus3.out","r").read())
with self.zf.open("virus6") as fp: with self.zf.open("virus6") as fp:
rc = milter.feedFile(fp) rc = milter.feedFile(fp)
@@ -134,7 +138,8 @@ class BMSMilterTestCase(unittest.TestCase):
self.assertTrue(milter._bodyreplaced,"Message body not replaced") self.assertTrue(milter._bodyreplaced,"Message body not replaced")
self.assertTrue(milter._headerschanged,"Message headers not adjusted") self.assertTrue(milter._headerschanged,"Message headers not adjusted")
fp = milter._body fp = milter._body
open("test/virus6.tstout","wb").write(fp.getvalue()) with open("test/virus6.tstout","wb") as f:
f.write(fp.getvalue())
milter.close() milter.close()
def suite(): return unittest.makeSuite(BMSMilterTestCase,'test') def suite(): return unittest.makeSuite(BMSMilterTestCase,'test')