in reply to Re: Re: Re: Re: Re: Re: using CGI on HTTP::Request from HTTP::Daemon
in thread using CGI on HTTP::Request from HTTP::Daemon

Actually I am not sure I know how to fix it! Have a look at this test code (it hangs). This is a minimal case that simply shows how read() will block on reads from $conn.

#!/usr/bin/perl -w use strict; use HTTP::Daemon; use HTTP::Status; my $d = HTTP::Daemon->new( Reuse => 1, LocalPort => 80, ) or die "No daemon: $!\n"; warn "Ready to go!\n"; while (my $conn = $d->accept()) { serve_everything( $conn, $conn->get_request( 1 )); } sub serve_everything { my ($conn, $req) = @_; my $length = $req->content_length || 0; local *main::STDIN = $conn; my $data = ''; my $buf; if ( $length ) { print "Expecting $length bytes\n"; while( read( STDIN, $buf, 16 ) ) { print "Got: $buf\n"; $data .= $buf; } } else { $data = "Nothing Posted\n"; } my $HTML = qq!<pre>$data</pre> <hr> <FORM METHOD="POST" ACTION="http://localhost" ENCTYPE="mu +ltipart/form-data"> <INPUT TYPE="file" NAME="upload_file1" SIZE="42"> <INPUT TYPE="submit"> </FORM> !; $conn->send_response( HTTP::Response->new( 200, 'OK', HTTP::Headers->new( Content_Type => "text/html" ) , $HTML ) ); $conn->print( 'nope', $@ ) if $@; }

cheers

tachyon

  • Comment on Re: Re: Re: Re: Re: Re: Re: using CGI on HTTP::Request from HTTP::Daemon
  • Download Code

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Re: Re: using CGI on HTTP::Request from HTTP::Daemon
by PodMaster (Abbot) on May 26, 2004 at 04:48 UTC
    *boing* Unless I'm missing something, you solve it by adopting the CGI strategy, that is, you read until you've read CONTENT_LENGTH bytes (if its not greater than POST_MAX).

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

      No that's the whole point of the sample code. Try to read() CONTENT_LENGTH bytes - it will hang as read() is never returning 0/undef but is just blocking.

      The only way I found to make it work was to use this:

      if ( $length ) { print "Expecting $length bytes\n"; while ( length($data) < $length ) { last unless sysread( STDIN, $buf, 16 ); print "Got: $buf\n"; $data .= $buf; } }

      If you use a standard read() it will hang (buffered) but sysread bypasses the buffering and it works as expected. The length check effectively avoids the last read where even for sysread it will block if there is no data left.

      I will hack it into shape when I get a moment. It is good to have a failure test case in such a small portable package.....

      cheers

      tachyon