Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

PoCo::Server::HTTP and CGI Uploads

by OverlordQ (Hermit)
on Feb 21, 2004 at 20:55 UTC ( [id://330852] : perlquestion . print w/replies, xml ) Need Help??

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

Greetings monks!

Edit: Followed jeffa's suggestions and as I said here, it's dying because it cant find the 'file' param from the post.

Due to the backwards nature of IRC DCC's*, I am trying to create a 'File Bot' that will accept uploads through the web and then distribute the files through IRC. My problem lies in how to get CGI.pm working inside a PoCo::Server::HTTP session. Below you'll find the code I'm using. It dies with the errors:
Use of uninitialized value in concatenation (.) or string at filebot.pl line 149.
Use of uninitialized value in substitution (s///) at filebot.pl line 150.
Cannot do that because Is a directory at filebot.pl line 157.
The subs in question are
root_handler
and
post_handler
. And now for the horrible code:
#!/usr/bin/perl use warnings; use strict; use POE; use POE::Component::Server::HTTP; use POE::Component::IRC; use CGI ":standard"; use Fcntl; use Data::Dumper; sub CHANNEL () { "#REMFiles" } # Start an HTTP server. Run it until it's done, typicall forever, # and then exit the program. POE::Component::IRC->new("remnet"); my $nick = 'REMBot'; POE::Session->create( inline_states => { irc_disconnected => \&bot_reconnect, irc_error => \&bot_reconnect, irc_socketerr => \&bot_reconnect, _default => \&_default, _start => \&bot_start, connect => \&on_connect, autoping => \&bot_do_autoping, irc_001 => \&on_connected, }, ); POE::Component::Server::HTTP->new( Port => 42000, ContentHandler => { '/' => \&root_handler, '/post/'=> \&post_handler, } ); POE::Kernel->run(); exit 0; sub _default { my ( $event, $args ) = @_[ ARG0, ARG1 ]; $args ||= []; print "default: $event (@$args)\n"; return 0; } sub bot_start { my $kernel = $_[KERNEL]; my $heap = $_[HEAP]; my $session = $_[SESSION]; $kernel->post( remnet => register => "all" ); $kernel->yield("connect"); } sub on_connect { my ( $kernel, $heap ) = @_[ KERNEL, HEAP ]; $kernel->post( remnet => connect => { Nick => $nick, Username => 'FileBot', Ircname => 'POE::Component::IRC FileBot', Server => 'irc.remnetworks.org', Port => '6667', } ); } sub on_connected { my $kernel = $_[KERNEL]; my $heap = $_[HEAP]; my $session = $_[SESSION]; $kernel->post( remnet => join => CHANNEL ); $heap->{seen_traffic} = 1; $kernel->delay( autoping => 300 ); } sub bot_do_autoping { my $kernel = $_[KERNEL]; my $heap = $_[HEAP]; my $session = $_[SESSION]; $kernel->post( remnet => userhost => $nick ) unless $heap->{seen_t +raffic}; $heap->{seen_traffic} = 0; $kernel->delay( autoping => 300 ); } sub bot_reconnect { my $kernel = $_[KERNEL]; $kernel->delay( autoping => undef ); $kernel->delay( connect => 60 ); } sub root_handler { my ( $request, $response ) = @_; $response->code(RC_OK); $response->content( start_html("FileUploads") . start_form( -method => "post", -action => "/post", -enctype=> "multipart/form-data" ) . "File to Up: " . filefield(-name=>'file') . br() . submit( "submit", "submit" ) . end_form() . end_html() ); return RC_OK; } # Handle simple CGI parameters. # # This code was contributed by Andrew Chen. It handles GET and POST, # but it does not handle %ENV-based CGI things. It does not handle # cookies, for instance. Neither does it handle file uploads. sub post_handler { my ( $request, $response ) = @_; print Dumper $request; my $uploads = "/home/ovrlrdq/scripts/filebot/files"; my $cgi; if ($request->method() eq 'POST' ) { $cgi = new CGI( $request->content ); } else { $request->uri() =~ /\?(.+$)/; if ( define($1) ) { $cgi = new CGI($1); } else { $cgi = new CGI; } } print Dumper $cgi; my $file = $cgi->param("file"); $file =~ s/.*[\/\\](.*)/$1/gi; $file = lc $file; my $upload_filehandle = $cgi->upload("file"); $response->code(RC_OK); sysopen(UPLOADFILE, "$uploads/$file", O_WRONLY | O_EXCL | O_CREAT +) or die "Cannot do that because $!"; while ( <$upload_filehandle> ) { print UPLOADFILE or die "Cannot do that because $!"; } close UPLOADFILE or die "$!"; $response->content( start_html() . title("FileUpload Success") . p("File has been uploaded.") . end_html() ); $poe_kernel->post ( remnet => privmsg => CHANNEL, "Somebody upload +ed $file"); return RC_OK; }

Replies are listed 'Best First'.
Re: PoCo::Server::HTTP and CGI Uploads
by jeffa (Bishop) on Feb 22, 2004 at 06:21 UTC

    Use of uninit val in concat (.) or string at filebot.pl line 149. Use of uninit val in subst (s///) at filebot.pl line 150. Cannot do that because Is a directory at filebot.pl line 157.
    That's 2 warnings and 1 error. The warnings might not amount to anything, but something tells me that this line:
    $file =~ s/.*[\/\\](.*)/$1/gi;
    is going to break ... use File::Basename instead.

    The error is one of these two die's:

    sysopen( ... ) or die "Cannot do that because $!"; ... print UPLOADFILE or die "Cannot do that because $!";
    and i'd put my money on the first one. Make absolutely sure that the web server can create files in the directory and make sure that the file doesn't already exist (or take out O_EXCL from the sysopen call). You might also want to make sure that uploaded file handle is valid as well:
    die "not a Fh" unless ref($upload_filehandle) eq 'Fh';

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Humm that caught it, died with "not a Fh at filebot.pl line 153."
      Now . . to figure out why that's not working :)
      Edit: Humm changed the old line
      my $file = $cgi->param("file");
      to
      my $file = $cgi->param("file") or die "Cannot get file param: $!\n";

      And it dies with: "Cannot get param: "

      Edit: Latest verion will always be in my pad
      now it dies with the error:
      Cannot do upload: No child processes