A curious bug when generating mails with long filename attachments

Some app I work on needs to export some data and send it to customers in a traceable way. We need to make sure that we keep track of each filename, and also make sure that the customers can (maybe even months later) tell us which export file might need some handling. So we decided to use a rather verbose filename containing the customer name, a timestamp and the uuid of the export job eg export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip.

Generating and sending such a mail is quite easy using eg Email::Stuffer and Email::Sender::Simple:

 my $filename = 'export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8e871.zip';
    
    my $email = Email::Stuffer
       ->to(          $customer_email )
       ->cc(          $our_archive_email )
       ->from(        $sender )
       ->subject(     "Your data" )
       ->text_body(   "Please find your data attached" )
       ->attach_file( $filename )
       ->email;
    
    Email::Sender::Simple->send( $email, { transport => $smtp } );

I tested this using a local maildev and also via google mail (as we're using that for that project..). It also worked for the customers. Well, some customers...

PEBCAK?

One customer complained that they could not open the file (on Windows). The file actually is a password "protected" zip archive containing a CSV, so I assumed they had some problems with that setup and provided some detailed instruction on how to open / extract that file and make sure that Windows does not mangle the extensions etc. The customer was satisfied. I grumbled a bit about Windows and customers and went on to do other stuff.

Some time later, due to some stupidity on my part, we sent out that file as a regular CSV file (without packing it into zip). Again, the customer complained that they could not unpack the file after downloading it and adding a zip extension. That's when I started to wonder what was really going on, because I got the mail as a plain CSV file and never should the customer need to manually add an extension.

And what going on was that the customer did not get any file extensions, just a plain string, then manually added the (in that case wrong) extension zip and only then could proceed. And the customer was not using gmail, but something else.

So I tried to open the mail in mutt, and .. the attachment was indeed mangled: The filename was truncated, the extension missing.

Headers

This prompted a closer examination of the mail headers:

Content-Type: application/octet-stream;
   name*0=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c8;
   name*1=e871.zip
   name=export_some_customer_2024-03-25T16:20:12_fcdc290d-50cb-403d-981d-51c...

Ouch!

It seems that some part of the (40 years old?) email spec cannot handle long filenames, therefore they are broken into multiple lines.

And it seems that some mail clients can handle this multi line filenames, and some cannot handle them (among them mutt, which I find sad, but in this case lucky, because I'm not sure I would ever found the real bug and just assumed customer incompetence...)

Fix it

The fix was of course easy: pack the actual file (with the still long and very verbose filename) into a zip archive with a different, much shorter name.

But it was still interesting to learn that in that case the problem was not a stupid customer or an annoying OS, but the fact the email obviously needs to printable on a dot-matrix printer and therefor should not have more than 80 characters per line...

Update: dakkar pointed out the relevant RFC 2332, Section 3.