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: 251

Filed under:
|

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

Related posts about perl

Related posts about sockets