Skip to content

Instantly share code, notes, and snippets.

@kazuho
Created September 14, 2009 00:53
Show Gist options
  • Save kazuho/186407 to your computer and use it in GitHub Desktop.
Save kazuho/186407 to your computer and use it in GitHub Desktop.
#! /usr/bin/perl
use strict;
use warnings;
use HTTP::Parser::XS qw(parse_http_request);
use IO::Socket::INET;
my $max_req_size = 131072;
my $listen_sock = IO::Socket::INET->new(
Listen => SOMAXCONN,
LocalPort => 12345,
Proto => 'tcp',
ReuseAddr => 1,
) or die "failed to listen to port 12345:$!";
sub handle_request {
my ($conn, $env) = @_;
if ($env->{REQUEST_METHOD} ne 'GET') {
# todo return 403
return;
}
my $content = "hello world!\n";
my $keep_alive = ($env->{HTTP_CONNECTION} || '') =~ /keep-alive/i;
my $res = join(
"\r\n",
'HTTP/1.0 200 OK',
'Content-Type: text/plain',
'Content-Length: ' . length($content),
($keep_alive ? 'Connection: keep-alive' : ()),
'',
$content,
);
$conn->syswrite($res);
$keep_alive;
}
while (1) {
if (my $conn = $listen_sock->accept) {
my $buf = '';
my %env;
while (1) {
my $rlen = $conn->sysread(
$buf,
$max_req_size - length($buf),
length($buf),
);
last if ! defined($rlen) || $rlen <= 0;
my $reqlen = parse_http_request($buf, \%env);
if ($reqlen >= 0) {
# handle request
$buf = substr $buf, $reqlen;
if (! handle_request($conn, \%env)) {
last;
}
}
if ($reqlen == -2) {
# request is incomplete, do nothing
} elsif ($reqlen == -1) {
# error, close conn (TODO send 400)
last;
}
}
undef $conn;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment