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

My Firefox client just hangs using the below :
sub httpserv { my $socket = shift; my $buf; while(defined($buf = <$socket>)) { # nothing } print $socket "HTTP/1.0 200 OK\n"; print $socket "Cache-Control: no-cache \n"; print $socket "Server: Apache/2.2.23(Fedora)\n"; print $socket "Connection: close \n"; print $socket "Content-Type: text/html; charset=UTF-8\n"; print $socket "\n\n"; # Without this browser doesn't show H +TML Content print $socket "<HTML><HEAD><TITLE>\n"; print $socket "Got your message</TITLE></HEAD>\n"; print $socket "<BODY>Got your message</BODY></HTML>\n"; $socket->close(); }
But is superfast with the below code
sub httpserv { my $socket = shift; my $buf; while(defined($buf = <$socket>)) { last; # Without this it is like removing a +utoflush(1), # Without the "last;" the client conn +ection hangs; } print $socket "HTTP/1.0 200 OK\n"; print $socket "Cache-Control: no-cache \n"; print $socket "Server: Apache/2.2.23(Fedora)\n"; print $socket "Connection: close \n"; print $socket "Content-Type: text/html; charset=UTF-8\n"; print $socket "\n\n"; # Without this browser doesn't show H +TML Content print $socket "<HTML><HEAD><TITLE>\n"; print $socket "Got your message</TITLE></HEAD>\n"; print $socket "<BODY>Got your message</BODY></HTML>\n"; $socket->close(); }
Observe the last; in the while loop.

Replies are listed 'Best First'.
Re: what's with last;
by Corion (Patriarch) on Dec 30, 2007 at 21:23 UTC

    There is a difference between calling a routine httpserv and actually writing a http server. My guess is that you receive a Connection: keep-alive header (which you discard) and thus your first code tries to read forever from the socket. The second snippet of code never reads the headers sent by the browser and hence is fast.

    I suggest you look into using HTTP::Server::Simple if you want a simple HTTP server, or in the code I have here, Simple HTTP in under 100 lines.

    Update: Also see last as to what last does.

Re: what's with last;
by jasonk (Parson) on Dec 30, 2007 at 21:20 UTC

    Firefox is probably doing keep-alive by default, which means without the last your loop never ends, with the last its fast because you only go through the loop once, no matter how much data there is.


    We're not surrounded, we're in a target-rich environment!
Re: what's with last;
by NetWallah (Canon) on Dec 31, 2007 at 16:29 UTC
    Earlier replies (++) focus on the "right" way to address what you are trying to do.

    I'll try to guess and correct the intent of the code you currently have, and provide an easy way to make the code operational. Note: I did not say "correct". This may be useful if you just need a quick, functional hack.

    Your are experiencing this problem because you are using a BLOCKING socket read.

    The simplest adjustment would be to get rid of the "last", and move the closing curly-brace for the "while" such that it encloses all statements except the socket close.

    while(defined($buf = <$socket>)) { #Remove "last;" and closing brace ##print ..statements..etc ... } # Place Closing brace AFTER print statements $socket->close();

         "As you get older three things happen. The first is your memory goes, and I can't remember the other two... " - Sir Norman Wisdom

Re: what's with last;
by pengwn (Acolyte) on Jan 02, 2008 at 21:03 UTC
    Is there no way to match the keep-alive tcp packets from the client? hence it will be easier to terminate our socket.