dabriel dabriel - 1 month ago 16
Perl Question

Perl web server: How to route

As seen in my code below, I am using apache to serve my Perl web server. I need Perl to have multple routes for my client as seen in

my %dispatch
. If I figure one out I'm sure the rest will be very similar. If we look at my Subroutine
sub resp_index
, how can I modify this to link to my index.html file located in my root:
/var/www/perl
directory?

/var/www/perl/perlServer.pl
:

#!/usr/bin/perl

{
package MyWebServer;

use HTTP::Server::Simple::CGI;

use base qw(HTTP::Server::Simple::CGI);

my %dispatch = (
'/index.html' => \&resp_index,
# ...
);

sub handle_request {
my $self = shift;
my $cgi = shift;

my $path = $cgi->path_info();
my $handler = $dispatch{$path};
if (ref($handler) eq "CODE") {
print "HTTP/1.0 200 OK\r\n";
$handler->($cgi);
} else {
print "HTTP/1.0 404 Not found\r\n";
print $cgi->header,
$cgi->start_html('Not found'),
$cgi->h1('Not found'),
$cgi->end_html;
}
}

sub resp_index {
my $cgi = shift; # CGI.pm object
return if !ref $cgi;

my $who = $cgi->param('name');

print $cgi->header,
$cgi->start_html("index"),
$cgi-h1("THIS IS INDEX"),
$cgi->end_html;
}
}

my $pid = MyWebServer->new()->background();
print "Use 'kill $pid' to stop server.\n";

Answer

I think what you're asking is how do you serve a file from your web server? Open it and print it, like any other file.

use autodie;

sub resp_index {
    my $cgi  = shift;
    return if !ref $cgi;

    print $cgi->header;

    open my $fh, "<", "/var/www/perl/index.html";
    print <$fh>;
}

Unless this is an exercise, really, really, REALLY don't write your own web framework. It's going to be slow, buggy, and insecure. Consider a small routing framework like Dancer.

For example, mixing documents like index.html and executable code like perlServer.pl in the same directory invites a security hole. Executable code should be isolated in their own directory so they can be given wholly different permissions and stronger protection.


Let's talk about this line...

return if !ref $cgi;

This line is hiding an error. If your functions are passed the wrong argument, or no argument, it will silently return and you (or the person using this) will have no idea why nothing happened. This should be an error...

use Carp;
croak "resp_index() was not given a CGI object" if !ref $cgi;

...but really you should use one of the existing function signature modules such as Method::Signatures.

use Method::Signatures;

func resp_index(CGI $cgi) {
    ...
}
Comments