Perl MiniWebserver
Posted
by snikolov
on Stack Overflow
See other posts from Stack Overflow
or by snikolov
Published on 2010-05-31T08:25:40Z
Indexed on
2010/05/31
8:32 UTC
Read the original article
Hit count: 274
hey guys i have config this miniwebserver, however i require the server to download a file in the local directory i am getting a problem can you please fix my issue thanks
!/usr/bin/perl
use strict; use Socket; use IO::Socket; my $buffer; my $file; my $length; my $output;
Simple web server in Perl
Serves out .html files, echos form data
sub parse_form { my $data = $_[0]; my %data; foreach (split /&/, $data) { my ($key, $val) = split /=/; $val =~ s/+/ /g; $val =~ s/%(..)/chr(hex($1))/eg; $data{$key} = $val;} return %data; }
Setup and create socket
my $port = shift; defined($port) or die "Usage: $0 portno\n";
my $DOCUMENT_ROOT = $ENV{'HOME'} . "public"; my $server = new IO::Socket::INET(Proto => 'tcp', LocalPort => $port, Listen => SOMAXCONN, Reuse => 1); $server or die "Unable to create server socket: $!" ;
Await requests and handle them as they arrive
while (my $client = $server->accept()) { $client->autoflush(1); my %request = (); my %data;
{
-------- Read Request ---------------
local $/ = Socket::CRLF;
while (<$client>) {
chomp; # Main http request
if (/\s*(\w+)\s*([^\s]+)\s*HTTP\/(\d.\d)/) {
$request{METHOD} = uc $1;
$request{URL} = $2;
$request{HTTP_VERSION} = $3;
} # Standard headers
elsif (/:/) {
(my $type, my $val) = split /:/, $_, 2;
$type =~ s/^\s+//;
foreach ($type, $val) {
s/^\s+//;
s/\s+$//;
}
$request{lc $type} = $val;
} # POST data
elsif (/^$/) {
read($client, $request{CONTENT}, $request{'content-length'})
if defined $request{'content-length'};
last;
}
}
}
-------- SORT OUT METHOD ---------------
if ($request{METHOD} eq 'GET') {
if ($request{URL} =~ /(.*)\?(.*)/) {
$request{URL} = $1;
$request{CONTENT} = $2;
%data = parse_form($request{CONTENT});
} else {
%data = ();
}
$data{"_method"} = "GET";
} elsif ($request{METHOD} eq 'POST') {
%data = parse_form($request{CONTENT});
$data{"_method"} = "POST";
} else {
$data{"_method"} = "ERROR";
}
------- Serve file ----------------------
my $localfile = $DOCUMENT_ROOT.$request{URL};
Send Response
if (open(FILE, "<$localfile")) {
print $client "HTTP/1.0 200 OK", Socket::CRLF;
print $client "Content-type: text/html", Socket::CRLF;
print $client Socket::CRLF;
my $buffer;
while (read(FILE, $buffer, 4096)) {
print $client $buffer;
}
$data{"_status"} = "200";
}
else {
$file = 'a.pl';
open(INFILE, $file);
while (<INFILE>)
{
$output .= $_; ##output of the file
}
$length = length($output);
print $client "'HTTP/1.0 200 OK", Socket::CRLF;
print $client "Content-type: application/octet-stream", Socket::CRLF;
print $client "Content-Length:".$length, Socket::CRLF;
print $client "Accept-Ranges: bytes", Socket::CRLF;
print $client 'Content-Disposition: attachment; filename="test.zip"', Socket::CRLF;
print $client $output, Socket::CRLF;
print $client 'Content-Transfer-Encoding: binary"', Socket::CRLF;
print $client "Connection: Keep-Alive", Socket::CRLF;
#
#$data{"_status"} = "404";
#
}
close(FILE);
Log Request
print ($DOCUMENT_ROOT.$request{URL},"\n");
foreach (keys(%data)) {
print (" $_ = $data{$_}\n"); }
----------- Close Connection and loop ------------------
close $client;
}
END
© Stack Overflow or respective owner