Программист читал документацию на модуль HTTP::Daemon, захотел попробовать, и написал небольшой тестовый скрипт (вообще-то он просто взял пример из документации и внес кое-какие изменения).
use HTTP::Daemon;
use HTTP::Status;
# perl http_daemon.pl 10046
my $d = HTTP::Daemon->new(LocalPort => $ARGV[1]||8080) or die;
while (my $c = $d->accept) {
while (my $r = $c->get_request) {
if ($r->method eq 'GET'
&& $r->uri->path =~ m!^/tmp!
&& -f $r->uri->path
) {
$c->send_file_response($r->uri->path);
}
else {
$c->send_error(RC_FORBIDDEN);
}
}
$c->close;
undef($c);
}
Тестовый скриптик на 20 строк! И все равно он работал не совсем так, как предполагал программист.
Программист начал изучать Perl недавно, а до этого программировал на C.
Скрипт станет работать лучше, если исправить в нем всего один символ.
А пока скрипт всегда начинает слушать порт 8080, независимо от переданного параметра командной строки.
Передача параметров командной строки в программу в Perl очень похожа на таковую в C:
программа получает массив строк – каждый параметр в отдельной строке.
Но есть небольшое отличие: в C в самом первом элементе (то есть в argv[0]
)
содержится имя вызываемой программы, а собственно параметры начинаются с argv[1]
,
в то время как в Perl’е параметры начинаются сразу же с $ARGV[0]
,
а имя программы доступно в специальной переменной $0
.
Программист использовал $ARGV[1]
вместо $ARGV[0]
,
этого параметра скрипт не получал и всегда работал с портом по умолчанию.
Исправление:
use HTTP::Daemon;
use HTTP::Status;
# perl http_daemon.pl 10046
-my $d = HTTP::Daemon->new(LocalPort => $ARGV[1]||8080) or die;
+my $d = HTTP::Daemon->new(LocalPort => $ARGV[0]||8080) or die;
while (my $c = $d->accept) {
while (my $r = $c->get_request) {
if ($r->method eq 'GET'