Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

allowing form uploading

by sulfericacid (Deacon)
on Oct 15, 2002 at 16:42 UTC ( #205424=perlquestion: print w/ replies, xml ) Need Help??
sulfericacid has asked for the wisdom of the Perl Monks concerning the following question:

Using the script below, a simple mailing form, I was wondering if anyone could assist me in setting up a file upload for sending. I know I am not the best coder and some of you like to be rude and start yelling at me for how I wrote it, but please keep those comments to yourself from now on. This is the best I can do and would prefer not being mocked.

Thing is I am on a public webhost and I don't have access to any non-so-popular modules so keep that in mind. I'd prefer not using any modules, if possible, or rewriting the way the script is setup for mailing.

Please let me know what I should look up on or if you have a snipplet that will work, it would be greatly appreciated!

#!/usr/local/bin/perl ###### SpyderForm v1.0 ###### ## Created by Aaron Anderson ## ## sulfericacid@qwest.net ## ## website: http://secretrealmofme.hypermart.net/webstuff ## ## Please read the readme file prior to installation. ## ## If you cannot find readme, dl a copy from my site! ## use strict; # Let's have some fun my'ing things, shall me? my %form; my $sendmail; my $webmaster; my $yourname; my $thanks; use CGI; my $query = CGI->new; print $query->header; %form = %{$query->Vars}; ##################### BEGIN EDITING THIS SECTION ##################### +######## $sendmail = "/var/qmail/bin/qmail-inject"; $webmaster = 'sulfericacid@qwest.net'; ( $thanks = <<'END_OF_THANKS' ) =~ s/^\s+//gm ; Thank you for visiting my website! Things are always changing so I hope you pop back again! If you asked any questions, please allow upto 24 hours for a response. END_OF_THANKS $yourname = 'Aaron'; # $signame = 'Aaron Anderson\n'; # $sigurl = 'www.yourdowmain.com\n"; #################### STOP EDITING FOR NOW ############################ +######### ### Make sure things are being completed, die slackers! if ($webmaster eq "") { print "Webmaster, please include your email address!\n"; } if ($form{'usermail'} eq "") { print "Ok, buddy, how do you expect me to email you back if you FORGET + to leave yoru email address?!?\n"; } if ($form{'username'} eq "") { print "Please click back and type in your name so I can spy on you!\n" +; } if ($form{'message'} eq "") { print "Only a severe slacker would try to submit a form without leavin +g a message!\n"; } # Mail to Webmaster open (MAIL, '|-', "$sendmail -t") or die $!; print MAIL "To: $webmaster\n"; print MAIL "From: $form{'usermail'}\n"; print MAIL "Subject: Insert subject here!\n\n"; print MAIL "Name- $form{'username'}\n"; print MAIL "Url- $form{'userweb'}\n"; print MAIL "Message- $form{'message'}\n"; print MAIL "Ip- $ENV{'REMOTE_ADDR'}\n"; close (MAIL); # Mail to User open (MAIL, '|-', "$sendmail -t") or die $!; print MAIL "To: $form{'usermail'}\n"; print MAIL "From: $form{'weburl'}\n"; print MAIL "Subject: Thank you for signing my form!\n\n"; print MAIL "$thanks\n"; print MAIL "You said:\n"; print MAIL "$form{'message'}\n"; close (MAIL); # Let's give them something to look at, might as well, they were nice +enough to fill out the form! ####################### BEGIN EDITING HERE 2 ######################### +############# print <<end_of_results; <html> <head> <title>Results Page</title> </head> <table width="75%" border="0"> <tr> <td colspan="2"> <p>Thank you for filling out the form. If you are awaiting assis +tance and you asked a question, please allow upto 24 hours for my to get + back to you.</p> <p>- $yourname</p> </td> </tr> <tr> <td colspan="2"><font color="#9933CC">Here is a copy of what you s +ent...</font></td> </tr> <tr> <td width="9%"><font color="#666666">name:</font></td> <td width="91%"><font color="#999999">$form{'username'}</font></td +> </tr> <tr> <td width="9%"><font color="#666666">email:</font></td> <td width="91%"><font color="#999999">$form{'usermail'}</font></td +> </tr> <tr> <td width="9%"><font color="#666666">url:</font></td> <td width="91%"><font color="#999999"><a href="$form{'weburl'}">$f +orm{'weburl'}</a></font></td> </tr> <tr> <td width="9%"><font color="#666666">message:</font></td> <td width="91%"><font color="#999999">$form{'message'}</font></td> </tr> <tr> <td width="9%"><font color="#666666">Rec. IP:</font></td> <td width="91%"><font color="#999999">$ENV{'REMOTE_ADDR'}</font></ +td> </tr> <tr> <td width="9%">&nbsp;</td> <td width="91%">&nbsp;</td> </tr> </table> end_of_results

edited: Tue Oct 15 17:12:35 2002 by jeffa - added readmore tag s/<br>/<p>/g

Comment on allowing form uploading
Select or Download Code
Re: allowing form uploading
by sulfericacid (Deacon) on Oct 15, 2002 at 16:49 UTC
    Ugh, I meant to say I want the users to be able to send attachments via this script, sorry.
Re: allowing form uploading
by George_Sherston (Vicar) on Oct 15, 2002 at 17:33 UTC
    I can understand your reluctance to use modules or, for example, scripts written by others - understand, but not condone. It really *is* worth making the effort to get up the learning curve so you can do this. I speak as one who wasted time and effort not doing this for a long time. The fab thing about Perl is that for most of the things you want to do, someone else has already thought through the problem and written stuff to help you do it better. CPAN is your friend, and worth geting to know.

    You say your webhost doesn't allow you to use non-standard modules. Please don't let this stand in your way. Most of the modules you will want *are* standard by now. Or, on the other hand, there are many free or cheap webhosts that let you do what you want (for example install your own choice of modules) - cubesoft in the us or uklinux in uk are good.

    Finally, I encourage you not to be touchy about a vigorous critique of your code. Would you rather people sugar-coated it and didn't tell you what was really wrong? Anyway, a good beasting from merlyn as well as being good for the soul is very much a rite of passage around here. It's not personal.

    § George Sherston

    PS in answer to your substantive question I wouldn't dream of doing this without a module. Mail::Sendmail handles attachments, though not in a very memory-friendly way. See this faq for more. Then you'll need a form field in your original form, and you'll need to use CGI.pm to help you manage processing the form once uploaded. NB that you will want your form to be a multipart encoded form - if you're generating your form from CGI.pm, you can set this up using the start_multipart_form() method. Forty-five minutes reading the docs on CGI and Mail::Sendmail will be time well spent. Enjoy! And please come back here with any problems you encounter.
Re: allowing form uploading
by charnos (Friar) on Oct 15, 2002 at 18:12 UTC
    Firstly, in answer to your question, I agree with George_Sherston. Installing Mail::Sendmail seems like the way to go. I don't believe it's a standard module, but it appears to be a pure Perl module, so you should be able to download it from CPAN (see above link), upload it to your home directory, and add something like
    use lib "$ENV{HOME}"; use Mail::Sendmail;
    to your script (after configuring it).

    Secondly, you may not have deserved the severity of the browbeating you received, but you deserved some of it. I don't mean to fan the flames, but surely you must concede that asking a benevolent group of software professionals to help you write code that is truly very dangerous and deleterious to yourself, the Perl community, and the Internet itself. Sure, it may be only for a few users to abuse (before being shutdown), but it comes down to what you were told as a kid by your parents: "What if everyone threw their trash on the ground?" You can see that already there's a lot of insecurity over the web, and fostering one more leak is just out of the question. I think that merlyn thought that you were knowingly writing this hole to abuse yourself, though it appears to me that this is not true, though I can certainly see why he thought that (I did too until I read this post). Realize it was not necessarily the content of the code that was being attacked, it was the security.

    This is the best I can do and would prefer not being mocked.
    If you open yourself to suggestion (but not attack) from others, this doesn't have to be so. "Experience is a dear teacher, but fools will learn at no other." - Poor Richard's Almanac

    (Ok, so I stole that from The Mythical Man-Month ;) )

    Update: upon inspecting this, I don't think I made my own gut reaction to this code clear. I second merlyn's sentiment: Please do not deploy this code. It's great that you learned from writing real-world code, it really is, but this is not an Internet-ready email application, and shouldn't be deployed as one.
Re: allowing form uploading
by swiftone (Curate) on Oct 15, 2002 at 18:37 UTC
•Re: allowing form uploading
by merlyn (Sage) on Oct 15, 2002 at 18:45 UTC
    This code is still insecure. It allows the abuse of your server to send arbitrary mail to arbitrary addresses (minus a little boilerplate). The original suspect will not be traceable, but your server will get the brunt (rightfully so) of being an accessory to the crime.

    Please do not deploy this code. Please.

    -- Randal L. Schwartz, Perl hacker

Re: allowing form uploading
by true (Pilgrim) on Oct 16, 2002 at 05:13 UTC
    Want to parse your very own attachment uploads without
    using a module? That's what you were asking.
    Simpliest way i've used without a module is called 'cgi-lib.pl'
    It's a downloadable perl script you include in your perl
    script and can run on your webserver just fine.
    http://cgi-lib.berkeley.edu/

    I didn't get too deep into your code. I'd rather submit
    some helpful pointers which may guide you on your way.


    Basically you want perl to receive the form inputs from an
    html page on a visitor's computer. Two areas need
    setting up to do this by yourself with no module:
    1. html form needs an enctype modifier.
    Without this, your browser sends the
    contents of your form as a simple buffer.
    Make sure you have the following
    included in your html form tag code:
    <form method=post enctype='multipart/form-data'>
    Now that you did that, you need to read what
    was received in perl. There are a ton of helpful
    modules which will do this for you 1000 times better than
    little ole me could convey, but you said virtual host,
    without a module. Again, i remind you of cgi-lib.pl, see above.
    Tinkering with multi-type forms isn't an entire waste of
    time. You start to see how MIME works
    which can be handy for custom email readers.

    To start, take a look at what perl is sending you.
    Self-testing is the best learning tool here.
    In particular take a look at your ENV variables
    when you upload a file to your test script.
    In particular, look at $ENV{'CONTENT_TYPE'}.
    $ENV{'CONTENT_TYPE'} has a boundary modifier, parse this.
    You will use the boundary to delimit the remainder of your
    form. Once you know the delimiter you can split your
    uploaded content into it's seperate parts and begin to hack away.
    Each part has a HEAD and a BODY. The head tells
    you the filename, and describes the content.
    The BODY is the content (i.e. your image, or file)
    described by the HEAD.
    The HEAD and BODY are seperated by \n\n
    #Print your ENV variables so you can find your boundary foreach $key(keys %ENV){ print "$key...$ENV{$key}\n"; }
    jtrue
      It pained me to -- such a helpful (in spirit at any rate) node, but
      (A) in general I think it's a bad idea to encourage use of cgi-lib.pl instead of CGI.pm for all kinds of reasons including code re-use and long term optimisation for developer time;
      (B) I don't like solutions that aim to avoid using modules - mostly because I myself got burned by lazily pursuing such solutions, so I have the zeal of the reformed;
      (C) Even if, which I don't believe, there was a good reason for resisting *new* modules in the script, sulfericacid is already using CGI.pm, and it's super-perverse to *replace* it with cgi-lib.

      § George Sherston

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (10)
As of 2014-08-28 15:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (263 votes), past polls