Reputation: 1558
The following code is a (pseudo!) http server. It just sends back the http request.
The unexpected comportment occurs with ftp requests from browser, like ftp://localhost:8888/
. With this, the browser connects and stays connected forever.
I don't understand what is happening!
How can I control this behavior and ignore ftp requests?
#!/usr/bin/perl
use strict;
use Socket;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
use IO::Poll;
local *S;
socket (S, PF_INET , SOCK_STREAM , getprotobyname('tcp')) || die "socket: $!\n";
setsockopt (S, SOL_SOCKET, SO_REUSEADDR, 1) || die "setsockopt: $!\n";
bind (S, sockaddr_in(8888, INADDR_ANY)) || die "bind: $!\n";
listen (S, 10) || die "listen: $!\n";
fcntl(S, F_SETFL, fcntl(S, F_GETFL, 0) | O_NONBLOCK) || die "fcntl: $!\n";
my $poll=IO::Poll->new;
$poll->mask(*S => POLLIN|POLLOUT);
while( 1 ) {
$poll->poll();
for my $reader ( $poll->handles(POLLIN ) ) {
my $remote = accept (my $connection, $reader);
my $bytes= sysread $connection,my $header,1024;
if (defined $bytes) {
if ($bytes == 0 || (index $header,"\r\n\r\n") < 0) {
close $remote;
next;
}
} else {
close $connection;
next;
}
syswrite $connection,"HTTP/1.1 200 OK\r\n\r\n".$header;
close $connection;
}
}
Upvotes: 1
Views: 333
Reputation: 17718
Unlike HTTP, FTP begins with the server sending a greeting to the client. In this case, the client, thinking it's talking to an FTP server, waits for an FTP hello, while the server, thinking it's talking to an HTTP client, is waiting for it to send an HTTP command.
The solution is to set a timeout for the client socket ($connection
) before attempting sysread.
Upvotes: 4