Perl 网络服务器:如何路由
Perl web server: How to route
正如我在下面的代码中看到的,我正在使用 apache 来为我的 Perl 网络服务器提供服务。我需要 Perl 为我的客户端提供多个路由,如 my %dispatch
中所示。如果我想出一个,我相信其余的会非常相似。如果我们查看我的子例程 sub resp_index
,我如何将其修改为 link 到位于根目录中的 index.html 文件:/var/www/perl
目录?
/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";
我想您要问的是如何从您的网络服务器提供文件?打开它并打印它,就像任何其他文件一样。
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>;
}
除非这是一个练习,否则真的、真的、真的不要编写自己的 Web 框架。这将是缓慢的、错误的和不安全的。考虑一个像 Dancer.
这样的小型路由框架
例如,将 index.html
之类的文档和 perlServer.pl
之类的可执行代码混合在同一目录中会引发安全漏洞。可执行代码应该隔离在它们自己的目录中,这样它们就可以获得完全不同的权限和更强的保护。
我们来谈谈这一行...
return if !ref $cgi;
这一行隐藏了一个错误。如果你的函数传递了错误的参数,或者没有参数,它会默默地 return 而你(或使用它的人)将不知道为什么什么都没有发生。这应该是一个错误...
use Carp;
croak "resp_index() was not given a CGI object" if !ref $cgi;
...但实际上您应该使用现有的函数签名模块之一,例如 Method::Signatures.
use Method::Signatures;
func resp_index(CGI $cgi) {
...
}
正如我在下面的代码中看到的,我正在使用 apache 来为我的 Perl 网络服务器提供服务。我需要 Perl 为我的客户端提供多个路由,如 my %dispatch
中所示。如果我想出一个,我相信其余的会非常相似。如果我们查看我的子例程 sub resp_index
,我如何将其修改为 link 到位于根目录中的 index.html 文件:/var/www/perl
目录?
/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";
我想您要问的是如何从您的网络服务器提供文件?打开它并打印它,就像任何其他文件一样。
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>;
}
除非这是一个练习,否则真的、真的、真的不要编写自己的 Web 框架。这将是缓慢的、错误的和不安全的。考虑一个像 Dancer.
这样的小型路由框架例如,将 index.html
之类的文档和 perlServer.pl
之类的可执行代码混合在同一目录中会引发安全漏洞。可执行代码应该隔离在它们自己的目录中,这样它们就可以获得完全不同的权限和更强的保护。
我们来谈谈这一行...
return if !ref $cgi;
这一行隐藏了一个错误。如果你的函数传递了错误的参数,或者没有参数,它会默默地 return 而你(或使用它的人)将不知道为什么什么都没有发生。这应该是一个错误...
use Carp;
croak "resp_index() was not given a CGI object" if !ref $cgi;
...但实际上您应该使用现有的函数签名模块之一,例如 Method::Signatures.
use Method::Signatures;
func resp_index(CGI $cgi) {
...
}