Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister

Re^10: file upload and IO::Handle

by rowdog (Curate)
on Sep 10, 2010 at 15:47 UTC ( #859654=note: print w/replies, xml ) Need Help??

in reply to Re^9: file upload and IO::Handle
in thread file upload and IO::Handle

Get rid of the [

$q = CGI->new(\&hook [,$sess_ref [,$use_tempfile]]);

That's the example from CGI showing the optional syntax. What it means is that you can use it like

$q CGI->new(\&hook);
$q = CGI->new(\&hook, $sess_ref);
$q = CGI->new(\&hook, $sess_ref, $use_tempfile);

Once you get that squared away, you should see hook getting called.

Replies are listed 'Best First'.
Re^11: file upload and IO::Handle
by Anonymous Monk on Sep 10, 2010 at 20:03 UTC
    Thanks rowdog, that got rid of the error, still not working however... tried it with the session they are logged in with and with a temp session both:
    ### Filename: ## subs in file: #hook $| = 1; $q = new CGI (\&hook, $sess_ref); # CGI->new(\&hook, $sess_ref); ## T +ried it with both of these, neither worked # Also tried both of these: #$q = new CGI (\&hook, $sess_ref, $use_tempfile); # CGI->new(\&hook, $ +sess_ref, $use_tempfile); # Neither worked $_sloc = '/tmp/s'; # This is the file upload hook, where we can update our session # file with the dirty details of how the upload is going. sub hook { my ($filename,$buffer,$bytes_read,$file) = @_; my ($sessid) = $ENV{QUERY_STRING}; my $length = $ENV{'CONTENT_LENGTH'}; my $percent = 0; if ($length > 0) { # Don't divide by zero. $percent = sprintf("%.1f", (( $bytes_read / $length ) * 100) ); } if($file) { $file->attr("_uploadUpdateStatus_",join(':',$bytes_read,$lengt +h,$percent)); } # Write this data to the session file. open (SES, ">$_sloc/$sessid.session"); print SES "$bytes_read:$length:$percent"; close (SES); } my $action = $q->param("view"); if ($action eq "upl") { # Make a file upload hook. # They are first submitting the file. This code doesn't really + run much # until AFTER the file is completely uploaded. my $sessid = $q->param("sessid") || $ENV{QUERY_STRING}; open (SES,">$_sloc/$sessid.session") or die "Could not locate +file: $! $_sloc/$sessid.session;"; print SES "1:1:1"; close (SES); my $filename = $q->param("incoming"); my $handle = $q->upload("incoming"); $filename =~ s/(?:\\|\/)([^\\\/]+)$/$1/g; # Copy the file to its final location. open (FILE, ">/home$_website_username/www/Videos/$filename") o +r die "Can't create file: $!"; my $buffer; while (read($handle,$buffer,2048)) { print FILE $buffer; } close (FILE); # Delete the session file. unlink("$_sloc/$sessid.session"); # Done. $_tfile = "/home$_website_username/www/Videos/" . $filename; $type = uploadInfo($filename)->{'Content-Type'}; ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$c +time,$blksize,$blocks) = stat($_tfile); if(-e "/home$_website_username/www/Videos/$filename") { $sess_ref->attr("show_message","success|I have successfull +y uploaded $filename to:$filename<br /> +File type: $type<br />File size: $size bytes<br />$_page_content<br / +>"); window_redirect("$_url?page=$in{page}&do=$in{do}$sess_id") +; } else { $sess_ref->attr("show_message","error|I could not upload t +he file: $filename to:$filename<br />Fi +le type: $type<br />File size: $size bytes<br />$_page_content"); window_redirect("$_url?page=$in{page}&do=$in{do}$sess_id") +; } } elsif ($action eq "ping") { # Now the meat of the CGI script. print "Content-Type: text/html\n\n"; # Checking up on the status of the upload. my $sessid = $q->param("sessid"); # Exists? if (open(OUTF, "$_sloc/$sessid.session")) { my $data = <OUTF>; close (OUTF); print "$data"; } elsif($sess_ref) { $data = $sess_ref->attr("_uploadUpdateStatus_"); print "$data"; } else { print "Error reading Upload progress...$sessid $! $_sloc/$ +sessid.session"; } if($sess_ref) { $sess_ref->close(); } if($dbh) { $dbh->disconnect(); } exit; } else { my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9 ); $_newSessId = $_un . join("", @chars[ map { rand @chars } ( 1 +.. 10 ) ]); $_page_content .= qq~ <div id="webform"> <fieldset id="upload_form"> <legend>Approved Upload System</legend><br /> <br /> Hello, you have been verified as allowed to upload + files to the Videos directory for the .com website...<br /> <br /> Please use the system below to upload files to thi +s directory.<br /> <br /> ~ . start_multipart_form(-name=>"uploadFile", -act +ion=>url() . '?' . $_newSessId, -method=>"POST", -onSubmit=>"return s +tartUpload();", id=>"theform") . hidden(-name=>"page") . hidden(-name=>"do") . hidden(-name=>"sessid", -value=>$_newSessId, -over +ride=>1) . hidden(-name=>"view", -value=>"upl", -override=>1) + . $hidden_sess_id . filefield(-name=>'incoming', -class=>'formfield', -size=>50, -maxlength=>80) . qq~<br /> <br /> ~ . submit(-name=>"choice", -value=>"Upload The File", -cl +ass=>"submit") . qq~<br /> <br />~ . end_form() . qq~ </fieldset> <div id="progress-div" style="display: none; width +: 600px; margin: auto"> <fieldset style="width: 600px;"> <legend>Upload Progress</legend><br /> <br /> <div id="trough"> <div id="bar" style="width: 0%"></div> </div> Received <span id="received">0</span>/<span id +="total">0</span> (<span id="percent">0</span>%)<br /> <div id="debug">Uploading</div> </fieldset><br /> <br /> </div> <br /> <br /> </div><br /> <br /> ~ . q~ <script type="text/javascript"> // a jquery-like function, a shortcut to document.getElementBy +Id function $(o) { return document.getElementById(o); } // This function is called when submitting the form. function startUpload() { // Hide the form. document.getElementById('upload_form').style.display = "no +ne"; // Show the progress div. document.getElementById('progress-div').style.display = "b +lock"; // Begin making ajax requests. setTimeout("ping()", 1000); // Allow the form to continue submitting. return true; } // Make an ajax request to check up on the status of the uploa +d function ping() { var ajax = new XMLHttpRequest();"GET", "index.cgi?page=~.$in{page}.q~&do=~.$in{d +o}.q~&view=ping&sessid=~.$_newSessId.q~&" + "rand=" + Math.floor(Math +.random()*99999) + "~.$sess_id.q~", true); ajax.onreadystatechange = function () { if (ajax.readyStat +e == 4) { parse(ajax.responseText);}}; ajax.send(null); } // React to the returned value of our ping test function parse(txt) { var parts = txt.split(":"); document.getElementById("debug").innerHTML = document.getE +lementById("debug").innerHTML + "." + parts[0] + ';' + parts[1] + ';' + + parts[2] + ';'; if (parts.length == 3) { document.getElementById("received").innerHTML = parts[ +0]; document.getElementById("total").innerHTML = parts[1]; document.getElementById("percent").innerHTML = parts[2 +]; document.getElementById("bar").style.width = parts[2] ++ "%"; } // Ping again! setTimeout("ping()", 1000); } </script>~; } 1;
    What am I doing wrong? I cannot seem to get it working, even if I have the hook open a debug file and write anything to it, nothing happens. I tried it just using $sessid.session and when that did not work, I created a global file in: /tmp named: s with 777 permissions, still it does not work (we are on a dedicated server behind a firewall so I did not mind doing that, I know it is safe).

    Any idea why this does not work?


      No, I don't really know why and it's honestly a lot of code to wade through. The main reason that you don't know is because you never check to see if things succeed or fail. Here's what I mean, in your hook sub, you have this code.

      open (SES, ">$_sloc/$sessid.session"); print SES "$bytes_read:$length:$percent"; close (SES);

      From my point of view, that's an error, what happens if you can't open the file? You just blindly write to it anyhow and the whole script ought to fail right there. As I said before, ALWAYS CHECK THE RETURN FROM OPEN. The simple fix is

      open (SES, ">$_sloc/$sessid.session") or die $!; print SES "$bytes_read:$length:$percent"; close (SES);

      Then try it and see if anything shows up in the server logs. After that, start the debugging process... use warn statements to ensure your variables contain what they ought to. Stick a warn @_; as the first line of the hook subroutine to be sure it's getting called and check that the parameters are sane. Then comment out the warn lines when it's working right.

        It might be simpler to add
        use autodie;
        at the top of the script, better error messages at least
      my ($sessid) = $ENV{QUERY_STRING}; Are you using taint checking (#!/usr/bin/perl -T --)? sessid could contain evil characters....

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://859654]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2020-09-30 22:24 GMT
Find Nodes?
    Voting Booth?
    If at first I donít succeed, I Ö

    Results (170 votes). Check out past polls.