Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

CGI hook

by datannen (Novice)
on Aug 08, 2006 at 00:15 UTC ( [id://566038]=perlquestion: print w/replies, xml ) Need Help??

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

I have this simple code:
#!/usr/local/bin/perl -w use CGI; use Fcntl qw(:DEFAULT :flock); my $data; my $hook_called; my $cgi = CGI->new(\&_hook, $data); sub _hook { my ($filename, $buffer, $bytes_read, $data) = @_; if (not $hook_called) { print $cgi->header(); $hook_called=1; } else { print "Read $bytes_read bytes of filename\n"; } $hook_called += $bytes_read; }
and post this simple form to it:
<FORM action="/cgi-bin/test.cgi" method="post" enctype="multipart/form +-data"> <input value="1154632892005" name="unique" type="hidden"> <INPUT TYPE="FILE" NAME="file"> <INPUT type="submit" value="Send"> <INPUT type="reset"> </FORM>
but, I get NO output. The hook callback doesn't seem to be getting called at all. What am I doing wrong?

Replies are listed 'Best First'.
Re: CGI hook
by rhesa (Vicar) on Aug 08, 2006 at 02:05 UTC
    Have a look at Apache2::UploadProgress.

    Update: the upload hook that you pass into new() only takes effect on file uploads, not on generic POST requests.

    Here's a little script that lets you test it. You will soon notice that the upload hook - while working as intended - is completely useless. The reason for this is that under regular CGI, you simply don't get to send output to the browser before the entire post has been received. To give feedback while the upload is in progress, you must trick the webserver into letting you, and that's why Apache2::UploadProgress is a much better tool than rolling your own.

    use strict; use warnings; use CGI; my $hook_called; my $cgi = CGI->new( \&_hook ); print $cgi->header(), $cgi->start_html("FOO"), $cgi->start_multipart_form, $cgi->filefield('file'), $cgi->submit, $cgi->end_form; sub _hook { my ( $filename, $buffer, $bytes_read, $data ) = @_; if( !$hook_called ) { print "Content-Type: text/html; charset=ISO-8859-1\n\n"; # +$cgi is not defined here $hook_called = 1; } else { print "Read $bytes_read bytes of filename\n"; } $hook_called += $bytes_read; } print $cgi->end_html;
Re: CGI hook
by ikegami (Patriarch) on Aug 08, 2006 at 00:27 UTC

    Even without change, your code outputs a telling warning.

    Adding use strict makes the error crystal clear.

    Update: Apparently, that's not the only problem. I can't figure it out at the moment.

Re: CGI hook
by Zaxo (Archbishop) on Aug 08, 2006 at 01:41 UTC

    I don't think there's any provision in CGI.pm's new function for a coderef as argument. It won't be called, it will just be stringified and taken as a field name.

    Calling new with arguments overrides GET or POST input, leaving requests unhandled. That may be confusing your idea of what's happening.

    Clearly, you're looking for a callback to handle some sort of runtime condition - at least that's what your question sounds like. It's probably one of our famous X-Y questions. What are you really trying to accomplish?

    After Compline,
    Zaxo

      I don't think there's any provision in CGI.pm's new function for a coderef as argument.

      You should have checked the docs before replying.

      You can set up a callback that will be called whenever a file upload is being read during the form processing. This is much like the UPLOAD_HOOK facility available in Apache::Request, with the exception that the first argument to the callback is an Apache::Upload object, here it's the remote filename.

      $q = CGI->new(\&hook [,$data [,$use_tempfile]]); sub hook { my ($filename, $buffer, $bytes_read, $data) = @_; print "Read $bytes_read bytes of $filename\n"; }

        In my CGI.pm, that passage reads,

                   You can set up a callback that will be called whenever a
               file upload is being read during the form processing. This
               is much like the UPLOAD_HOOK facility available in
               Apache::Request, with the exception that the first
               argument to the callback is an Apache::Upload object, here
               it's the remote filename.
        
                $q = CGI->new();
                $q->upload_hook(\&hook,$data);
        
                sub hook
                {
                       my ($filename, $buffer, $bytes_read, $data) = @_;
                       print  "Read $bytes_read bytes of $filename\n";
                }
        
        
        The hook is not an argument to new, but is set in the upload_hook method.

        After Compline,
        Zaxo

      I want to be able to upload a file and perform an action within the _hook subroutine every 4000 bytes or so.
      Calling new with arguments overrides GET or POST input, leaving requests unhandled.

      Just to niggle, CGI->new will handle whatever you call it with, including any GET or POST input:

      if ($ENV{'REQUEST_METHOD'} eq "GET" and $ENV{'QUERY_STRING'}) { (my $query = $ENV{'QUERY_STRING'}) =~ s/$munge//; my $q = CGI->new($query); }

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (3)
As of 2024-04-26 05:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found