njweatherman has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I am trying to attach a Microsoft Word Document to an email message using the module net::smtp. I would use Mime::lite, unfortunately, our web server will not install it. In any case, the program works by attaching the correct file name, except it sends a blank file. How do I attach the file to the document so the user can open or save the document on his / her computer?

As always thanks!

use Net::SMTP;
$host = "";
$username = "test";
$password = "test123";
$filename = "S:/Documents/test.doc";
$name = "test.doc";
$email = "";

# Create a new SMTP object
$smtp = Net::SMTP->new($host);
$smtp->auth ( $username, $password ) or die "Could not authenticate $!";

$smtp->datasend("From: test\\n");
$smtp->datasend("To: $email\n");
$smtp->datasend("Subject: Test Message\n");
$smtp->datasend("MIME-Version: 1.0\n");
$smtp->datasend("Content-Disposition: attachment; file= \"$filename\"\n");
$smtp->datasend("Content-Type: application/msword; name= \"$name\"\n");

Replies are listed 'Best First'.
Re: Sending An Attachment Using Net::SMTP
by bart (Canon) on Mar 22, 2008 at 08:02 UTC
    You're not actually sending the contents of the file. For that, you have to open the file, read it (possibly in blocks), and send it through SMTP.

    You really ought to encode it in base64 encoding, for which you'd be best off installing a module, if you don't have it already: MIME::Base64, or as a fallback measure, MIME::Base64::Perl.

    The latter is in Pure Perl, you can install it by just copying it to a proper location.

      Is there a way to just attach the file to the email message so the user can just open the MS Word document on his / her own machine?

        When you "just" attach a document using your mail client behind the scenes it creates a multipart MIME document, encodes the attachment and embeds it into the data that is sent to the SMTP server. When you use Perl to do the same thing you also must create a multipart MIME document, encode the document and embed it the data sent to the SMTP server.

        Your options are

        • Write it all yourself
        • Use modules from CPAN

        What do you mean by "our web server will not install it"? Do you mean that your system administrator won't install it? If so install the library somewhere you have write access to. You can then add the directory to the search path Perl uses to find libraries.

        perl Makefile.PL INSTALL_BASE=~njweatherman/lib make make test make install
        #!/usr/lib/perl use strict; use warnings; use lib qw(~njweatherman/lib);

        There is another option, if the person receiving the e-mail is on your network, or, if the document is accessible publicly.

        In these cases, simply send a LINK to the document via e-mail. No MIME required.

        "Publicly accessible" is intended to include SECURED access, such as via a (secured) FTP, HTTP with logon , Windows Share etc.

             "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

        Oh, you mean by magic?

        No. That's not how technology works, in the real world.

Re: Sending An Attachment Using Net::SMTP
by zentara (Archbishop) on Mar 22, 2008 at 13:39 UTC
Re: Sending An Attachment Using Net::SMTP
by alejandro (Initiate) on Feb 25, 2014 at 04:18 UTC

    Here is a working example of how to send multipart mail messages using Net::SMTP. Code for sending plain text, a plain text file, and a binary image (jpg) are provided.

    Hope this helps!

    #!/usr/bin/perl use Net::SMTP; use strict; use warnings; use MIME::Base64 qw( encode_base64 ); #use MIME::Base64 qw( decode_base64 ); my $from = ''; my $to = ''; my $attachBinaryFile= 'test.jpg'; my $attachTextFile = 'test.txt'; my $boundary = 'frontier'; open(DAT, $attachTextFile) || die("Could not open text file!"); my @textFile = <DAT>; close(DAT); my $smtp = Net::SMTP->new('', Timeout => 60) || die("Coul +d not create SMTP object."); print "Sending mail\n"; $smtp->mail($from); $smtp->recipient($to, { SkipBad => 1 }); $smtp->data(); $smtp->datasend("To: $to\n"); $smtp->datasend("From: $from\n"); $smtp->datasend("Subject: Multi part test\n"); $smtp->datasend("MIME-Version: 1.0\n"); $smtp->datasend("Content-type: multipart/mixed;\n\tboundary=\"$boundar +y\"\n"); $smtp->datasend("\n"); $smtp->datasend("--$boundary\n"); $smtp->datasend("Content-type: text/plain\n"); $smtp->datasend("Content-Disposition: quoted-printable\n"); $smtp->datasend("\nToday\'s files are attached:\n"); $smtp->datasend("\nHave a nice day! :)\n"); $smtp->datasend("--$boundary\n"); $smtp->datasend("Content-Type: application/text; name=\"$attachTextFil +e\"\n"); $smtp->datasend("Content-Disposition: attachment; filename=\"$attachTe +xtFile\"\n"); $smtp->datasend("\n"); $smtp->datasend("@textFile\n"); $smtp->datasend("--$boundary\n"); $smtp->datasend("Content-Type: image/jpeg; name=\"$attachBinaryFile\"\ +n"); $smtp->datasend("Content-Transfer-Encoding: base64\n"); $smtp->datasend("Content-Disposition: attachment; filename=\"$attachBi +naryFile\"\n"); $smtp->datasend("\n"); my $buf; open(DAT, "../uploads/$attachBinaryFile") || die("Could not open binar +y file!"); binmode(DAT); local $/=undef; while (read(DAT, my $picture, 4096)) { $buf = &encode_base64( $picture ); $smtp->datasend($buf); } close(DAT); $smtp->datasend("\n"); $smtp->datasend("--$boundary\n"); $smtp->dataend(); $smtp->quit; print "Mail sent\n"; exit;
    A PERL is but bytes arranged under a client's pressure!

      To make encoding to base64 better, use a chunk/buffer that is a multiple of 57 bytes. This will enable sending of large files.

      In the code that alejandro posted, the line:

      while (read(DAT, my $picture, 4096)) {

      could become:

      while (read(DAT, my $picture, 72*57)) {

      To read a bit more about this, see the examples section in

Re: Sending An Attachment Using Net::SMTP
by Jenda (Abbot) on Mar 24, 2008 at 23:05 UTC