Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Sending a email with file attachment with LWP ONLY

by MarkusH (Initiate)
on Jul 05, 2012 at 10:10 UTC ( #980010=perlquestion: print w/ replies, xml ) Need Help??
MarkusH has asked for the wisdom of the Perl Monks concerning the following question:

Dear perlmonks, Is there any solution to send a multipart email ( a message and two files as attachemnt) without using MIME or MAIL? for what i know, you can send a email containing a text via code this:
my $req = POST( "mailto:".$rec_email, From =>"$send_email", Subject =>"$subject has changed", Content_Type=> 'text/plain; charset=ISO-8859-1 ; boundary="--text" +', Content=>"Dear $rec_name,we want to inform you <wall of text>" ); #and then, i want to include 2 files here
I solved this problem using MIME, but my customer insists on avoid using this it module. I am not really successfull in finding a solution to this problem...so has anybody a idea/experience in this case? best regards, markus

Comment on Sending a email with file attachment with LWP ONLY
Download Code
Re: Sending a email with file attachment with LWP ONLY
by marto (Chancellor) on Jul 05, 2012 at 10:18 UTC

    Tell your customer it's going to cost them a lot of money for you to invent and maintain a sane way of sending emails without using one of the recommended, maintained and tested modules. Perhaps you could ask why they don't want to use a tried and tested method and what they hope to gain from going down another route.

Re: Sending a email with file attachment with LWP ONLY
by mithaldu (Monk) on Jul 05, 2012 at 11:25 UTC
    my customer insists on avoid using this
    Why?

    If you don't know why, ask your customer that question.

    Very often you can work out how to explain that their motivations might be misguided when you know exactly what their motications are.
Re: Sending a email with file attachment with LWP ONLY
by Anonymous Monk on Jul 05, 2012 at 11:30 UTC
    Well, if you don't use MIME, you're not sending email -- even if you send through a web interface ( webmail ), it must uses MIME on your behalf -- otherwise it isn't email (can't use email addresses)

      You're giving people wrong ideas with your sloppy wording.

      if you don't use MIME, you're not sending email

      It is possible to compose Internet messages without MIME, in fact more than half of my outgoing emails are not MIME. Mind that the "E" in the acronym is for "extensions".

      Sending email is a different concern.

      even if you send through a web interface ( webmail )

      It is clear from the problem description that the end user invokes his local desktop mail client through the mailto URI in that Web application.

      it must uses MIME on your behalf -- otherwise it isn't email (can't use email addresses)

      Email addresses are a different concern. The problem description was about attachments, and we should suppose the addresses in that mailto URI work just fine.

        You're giving people wrong ideas with your sloppy wording.

        On the other hand, you're giving sloppy-question-asker wrong ideas with your hypertechnical but ultimately irrelevant corrections

        It is clear from the problem description that the end user invokes his local desktop mail client through the mailto URI in that Web application.

        No. What does the local-desktop-mail-client have to do with LWP?

Re: Sending a email with file attachment with LWP ONLY
by tobyink (Abbot) on Jul 05, 2012 at 13:19 UTC

    I'm not entirely sure what you think that boundary parameter is doing in your Content-Type header. The boundary parameter is only defined for multipart content types, not text/plain.

    What exactly do you mean by "without using MIME or MAIL"? Are you referring to some specific Perl modules? Or do you mean that you want to avoid your mail conforming to the MIME specification? If the latter, you should be aware that MIME is the only commonly supported mechanism for attaching files to e-mail, so if you use any non-MIME mechanism for attaching files, it's unlikely to be recognised by recipients.

    If you just want to avoid using Perl MIME modules, it's not especially difficult. You'll need a base64 or quoted-printable encoding function, but once you've got that it's quite simple.

    use LWP::UserAgent; use HTTP::Request::Common 'POST'; # I'm using encode_base64 from MIME::Base64, but you can use something # else if you prefer. use MIME::Base64 'encode_base64'; # I'm using the DateTime module to generate the "Date" header for my # e-mail, but you can use something else if you prefer. use DateTime; my @parts = ( { 'Content-Type' => 'text/plain', 'Content-Disposition' => 'inline', 'CONTENT' => 'Hello world', }, { 'Content-Type' => 'text/html', 'Content-Disposition' => 'attachment; filename=example.html', 'CONTENT' => '<!doctype html><title>HW</title><p>H +ello world', }, { 'Content-Type' => 'text/plain', 'Content-Disposition' => 'attachment; filename="another exampl +e.txt"', 'CONTENT' => 'Hello world', }, ); my $boundary = join '-', map { sprintf '%08x', rand(2**32) } 0..3; my $body = "This is a multipart message in MIME format.\n\n"; foreach (@parts) { my %part = %$_; my $part_body = delete $part{CONTENT}; $body .= "--$boundary\n"; $body .= "$_: $part{$_}\n" for keys %part; $body .= "Content-Transfer-Encoding: base64\n"; $body .= "\n"; $body .= encode_base64($part_body)."\n"; } $body .= "--$boundary--\n"; my $req = POST( 'mailto:mail@tobyinkster.co.uk', From => 'tai@g5n.co.uk', Date => DateTime->now->strftime('%a, %d %b %Y %H:%M:%S %z' +), Subject => 'Test Message', Content_Type => qq(multipart/mixed; boundary="$boundary"), Content => $body, ); my $response = LWP::UserAgent->new->request($req);

    The above code is quite na´ve and there will no doubt be plenty of edge-cases it doesn't cover, but if you're using it in a small, tightly controlled place, it may be adequate.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      Thanks a LOT, your answer got me in the right direction! I tried something in this direction first, but i failed when i tried to combine multiple contents, my understanding of bondarys was false! Not as small as a solution with MIME or NET, but it will satisfy the problems requirement! @all: thanks to your responses! It interesting to see, in how many ways you can solve a problem in perl!
Re: Sending a email with file attachment with LWP ONLY
by aaron_baugher (Deacon) on Jul 05, 2012 at 13:31 UTC

    I think you need to start by clarifying some terms. What do you mean by MIME and MAIL? There are no modules by those names that I know of, though there are several in those namespaces. Is your customer opposed to all of them, or just certain ones?

    It's true that LWP understands the mailto: protocol, so it may be able to send a composed message for you. I'm really not sure how mailto through HTTP works, and I'd be surprised if you can count on it working with every web server. But even if it does, first you have to compose the message, and if the message is going to have attachments, you need MIME. That's what MIME is for. It encodes the file so it can pass through 7-bit SMTP, puts it in a standard wrapper, and adds headers to tell mail clients how to decode it.

    In the olden days, we sent files through email without MIME, by doing things like this:

    $ uuencode <me.gif | mail -s 'My Picture' friend@somewhere.com

    Then the friend would cut the encoded text out of the message and pass it through uudecode to get the original file. But there was no standard, and you had to do it all manually outside your mail client. MIME developed to standardize and automate the process.

    You could still do something like that today, but only if you're controlling both ends so you know how to decode your encodings. A client who wants to send attachments to anyone but says you can't use MIME, is like a client who hires you to drive nails but says you can't use a hammer. He'd better have a really good reason. Without knowing that reason, it's hard to suggest what would be an acceptable alternative.

    Aaron B.
    Available for small or large Perl jobs; see my home node.

      "It's true that LWP understands the mailto: protocol, so it may be able to send a composed message for you. I'm really not sure how mailto through HTTP works, and I'd be surprised if you can count on it working with every web server."

      LWP's support for "mailto:" URIs doesn't involve HTTP at all - it just invokes /usr/sbin/sendmail and sends the mail that way. Similarly when LWP is passed a "file:" URI, it will happily read the file off your local system without any HTTP anywhere.

      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        Thanks for the correction. The LWP man page just said the message is "passed on to the mail system," and since it's formatted just like a POST HTTP request, I didn't know if that was on the local system or a remote one as in a more typical HTTP request. I didn't see how it could possibly work reliably through a web server, but didn't want to make too many assumptions. Since sendmail isn't available on all systems, that seems like a fairly brittle way to do it, when there are other mail modules that will talk SMTP as well.

        Aaron B.
        Available for small or large Perl jobs; see my home node.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://980010]
Approved by DrHyde
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2014-08-30 11:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (293 votes), past polls