zentara has asked for the wisdom of the Perl Monks concerning the following question:
In the LWP script, the file uploads, and then the cgi returns a "thank you for uploading message", which LWP will display with
my $res = $ua->request($req); if ($res->is_success){print $res->as_string; }else{print $res->status_line; }
Now this is my pure Sockets version, and it works only if I close the socket after the file upload. The cgi script still sends out the "thankyou", but my sockets script can't read it. If I put in some code to read the socket for the "thank you", it just hangs, because the server still is in "read" and so is my script. So is there a command or some hex codes, which I can send after the file transfer finishes, which tells the apache server, to finish sending? Something like "End of Send", which signals a mode switch but dosn't close the socket?". How does LWP do it? In simple terms :-)?
#!/usr/bin/perl use warnings; use strict; use Socket; my $url = "http://zentara.zentara.net/~zentara/cgi-bin/up1.cgi"; my $upfile = shift || 'ztest.png'; my $host = "zentara.zentara.net"; $| = 1; my $start = times; my ( $iaddr, $paddr, $proto ); $iaddr = inet_aton($host); #$iaddr = ( gethostbyname($host) )[4]; $paddr = sockaddr_in( 80, $iaddr ); $proto = getprotobyname('tcp'); unless ( socket( SOCK, PF_INET, SOCK_STREAM, $proto ) ) { die "ERROR : init socket: $!"; } unless ( connect( SOCK, $paddr ) ) { die "no connect: $!\n"; } my $length = 0; open (UH,"+< $upfile") or warn "$!\n"; $length += -s UH; my @head = ( "POST /~zentara/cgi-bin/up1.cgi HTTP/1.1", "Host: zentara.zentara.net", "User-Agent: z-uploader", "Content-Length: $length", "Content-Type: multipart/form-data; boundary=zzzzzzzzzzzzzzzzzzz", "", "--zzzzzzzzzzzzzzzzzzz", "Content-Disposition: form-data; name=\"file\"; filename=\"$upfile\"", "Content-Type: application/octet-stream", "", "", ); #try to get total length my $header = join( "\r\n", @head ); $length += length($header); $head[3] = "Content-Length: $length"; $header = join( "\r\n", @head ); #recompute $length = -s UH $length += length($header); select SOCK; $| = 1; binmode SOCK; print SOCK $header; while( sysread(UH, my $buf, 8196 ) ){ if( length($buf) < 8196 ){ $buf = $buf."\r\n--zzzzzzzzzzzzzzzzzzz--\r\n"; syswrite SOCK, $buf, length($buf); }else{ syswrite SOCK, $buf, 8196 } print STDOUT '.', } close UH; select STDOUT; # here is where I think the EOT should be sent # so I could read the results page, but it hangs # the socket #my $data = (<SOCK>); #print "result->$data\n"; close SOCK;
In case anyone wants to play with it, here is the cgi script:
#!/usr/bin/perl use warnings; use strict; use CGI; use CGI::Carp 'fatalsToBrowser'; #my $maxsize = 1024 * 100; #max 100K my $maxsize = 1024 * 20000; #max 20M #$CGI::POST_MAX= $maxsize; # max 100K posts !not working right? #$CGI::DISABLE_UPLOADS = 1; # no uploads my $query = new CGI; my $upload_dir = "uploads"; #permissions for dir are set print $query->header(); if($ENV{CONTENT_LENGTH} > $maxsize){ print "file too large - must be less than $maxsize bytes"; exit; } my $file = $query->param("file"); my $filename = $file; $filename =~s/.*[\/\\](.*)/$1/; open (UPLOADFILE, ">$upload_dir/$filename"); $/= \8192; # sets 8192 byte buffer chunks, perldoc perlvar while ( <$file> ){ print UPLOADFILE $_; #select(undef,undef,undef,.05); #for testing } close UPLOADFILE; print <<END_HTML; <HTML> <HEAD> <TITLE>Thanks!</TITLE> </HEAD> <BODY bgcolor="#ffffff"><br> <P>Thanks for uploading file : $filename!</P> </BODY> </HTML> END_HTML
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: simulating LWP's "results" with pure sockets
by beauregard (Monk) on Mar 08, 2005 at 22:14 UTC | |
by zentara (Cardinal) on Mar 08, 2005 at 23:28 UTC |