Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected line-breaks when sending XML attachments using ActionMailer

My application stores a lot of XML files. A background job periodically sends some of those XML files to a specific mailbox. The mailer code is dead-simple:

class MailSender < ActionMailer::Base
    default :from => AppConfig.mail_from

    smtp_settings :address => AppConfig.smtp_host,
                  :username => AppConfig.smtp_user,
                  :password => AppConfig.smtp_pass

    def send_xml(record)
        f = record.filename.gsub("\\", "/") # converts \ to /
        f_short = arq.gsub(/.*\//, "") # extracts only the filename
        f_phys = "#{AppConfig.xml_root}#{arq}" # builds the physical filename

        headers["Return-Receipt-To"] = AppConfig.return_receipt

        attachments[f_short] = File.read(f_phys) if File.exists?(f_phys)

        mail :subject => "...",
             :to => AppConfig.mail_to
    end
end

However, for some reason, those XML are getting corrupted on transmission: the first line break gets added at column 987, and the following are added at column 990. After each break, a space is inserted. I think the picture says for itself:

col 1                                       col 990
|.................................................|
<?xml version="1.0"  ...  </IE><IM>321505493301<
 /IM><CNAE>4744001<  ...  00</pCOFINS><vCOFINS>0.00
 </vCOFINS></COFINS  ...  /prod><imposto><ICMS><ICM
 S40><orig>0</orig>  ...  <infAdic><infCpl>Permite 

I tried calling File.read myself on rails console, it works fine, no line breaks are added. So I assume the error should lie on the ActionMailer. Any tips?

Edit for clarification: Most of the XML document lie on a big, single line. I can't change it, since the XML are digitally signed - any change, including adding line breaks and indentation, breaks the digital signature.

like image 439
Fábio Batista Avatar asked Oct 25 '22 04:10

Fábio Batista


1 Answers

Answering the question that gave me the 'Thumbleweed' badge :)

I ended up encoding the file myself, and it's now working fine:

attachments[f_short] = {
  :encoding => 'base64',
  :content => Base64.encode64( File.read(f_phys) ).chomp
} if File.exists?(f_phys)
like image 162
Fábio Batista Avatar answered Nov 04 '22 20:11

Fábio Batista