[Pymilter] Change Body from header in a mail (newbie question)

Stuart D Gathman stuart at bmsi.com
Fri May 10 00:43:16 EDT 2013


On May 9, Abhijeet Rastogi transmitted in part:

> As we know, there are two "from" in a mail. The actual envelope
> mailfrom and the body from. I'm trying to change body "from" whenver
> "envelope mailfrom" and "body from" don't match.

A questionable goal, but certainly easy.

> For that, I picked the official example.
> http://pythonhosted.org/pymilter/milter-template_8py-example.html and
> edited the below code.
>
>  def header(self, name, hval):
>    if name == "From":
>        if self.F != hval:
>            self.log("<" + hval.strip("<>") + "via " + self.F.strip("<>") + ">")
>            hval = hval + "via" + self.F
>
>    self.fp.write("%s: %s\n" % (name,hval))     # add header to buffer
>    return Milter.CONTINUE
>
> I can see by adding "self.log" statements that the header is actually
> being changed but when I receive the mail, I still see the original
> body from. Why can that be so? I even tried the
> "Milter.set_flags(Milter.CURR_ACTS)", still it's not changing the body
> from.

Because you are only changing the copy of the header in your internal
buffer.  I added that buffer to the example because people kept asking,
"How do I collect all the headers to make a complete email (e.g. for
archiving)?"

> It's my first milter writing experience and I'm stuck at this. Any
> help would be highly appreciated.

Use chgheader to change the header in the MTA:

http://pythonhosted.org/pymilter/classMilter_1_1Base.html#a2debae177f22c9ae4c53644280a2cd10

Note that chgheader can only be called from eom.  In the bms.py milter,
I use a helper method:

   # addheader can only be called from eom().  This accumulates added
   # headers which can then be applied by alter_headers() in eom().
   def add_header(self,name,val,idx=-1):
     self.new_headers.append((name,val,idx))
     self.log('%s: %s' % (name,val))

Additional hooks may be needed in eoh() to add the new headers to your 
internal buffer, if used.

I did not implement chg_header (or even fully implement add_header), but
the same idea applies.  You might consider it for future milters.

In your case, I would just set self.from_header = None in envfrom(),
and set it to the desired value according to your logic if it needs
changing.  Then in eom():

   def eom():
     if self.from_header:
       self.chgheader('from',0,self.from_header)
     ...



More information about the Pymilter mailing list