×
Техническая документация

CGI-программы, использование Perl

Установка модулей Perl

Устанавливать модули Perl лучше всего используя CPAN shell. Необходимо зайти в unix shell и набрать команду:

perl -MCPAN -e shell

После этого можно установить любой модуль командой

install module::submodule

Например:

install Spreadsheet::Read.

Рекомендуем при первой настройке CPAN shell выбрать один из серверов-зеркал, перечисленных в категории «Europe/Russia».

В случае необходимости вы можете отредактировать конфигурационный файл — /home/uXXXXX/.cpan/CPAN/MyConfig.pm , где uXXXXX номер вашей виртуальной площадки.

Важно:

При первичном конфигурировании CPAN shell на вопрос:

Parameters for the 'perl Makefile.PL' command?
Typical frequently used settings:

     PREFIX=~/perl       non-root users (please see manual for more hints)

Your choice:  []
надо ответить:
Your choice:  [] PREFIX=~/perl

Именно в этом случае все необходимые модули будут корректно устанавливаться в ваш домашний каталог.

Установка модулей Perl с помощью Makefile.PL

К сожалению, не все модули можно установить с помощью CPAN, обладая ограниченным правами пользователя площадки. В следующем примере мы рассмотрим установку модуля String::CRC32.

Сначала найдем модуль на сайте http://search.cpan.org/, введя в строку поиска название этого модуля. Далее выбираем вторую ссылку из самого первого результата поиска:

http://search.cpan.org/~soenke/String-CRC32-1.4/

копируем url на модуль из ссылки Download;

загружаем архив на площадку:

wget http://search.cpan.org/CPAN/authors/id/S/SO/SOENKE/String-CRC32-1.4.tar.gz

распаковываем полученный архив:

tar xzf String-CRC32-1.4.tar.gz

выполняем следующие команды:

PERL5LIB=~/perl/lib;export PERL5LIB
perl Makefile.PL LIB=~/perl/lib PREFIX=~/perl/lib
make;make install

Чтобы использовать модуль, добавьте в скрипт следующую строку

push (@INC, "~/perl/lib/");
use String::CRC32;

Классификация ошибок

Ошибки делятся на шесть основных категорий (перечислены по степени сложности):

Ошибки формата файла

В операционных системах Unix, Windows для завершения строки используются разные символы.

Это может вызвать проблемы, если вы редактируете свою программу в операционной системе одного типа, а затем запускаете ее в другой ОС. Иными словами, если вы создаете и (или) редактируете свои программы на Windows, а ваш Internet-провайдер использует Web-сервер на базе Unix, необходимо удостовериться, что файл вашей программы сохранялся с соответствующими разделителями строк.

Один из простых способов сделать это — открыть файл на своем Web-сервере и посмотреть, есть ли в конце, каждой строки какие-нибудь странные символы.

Только надо быть уверенным, что ваш редактор показывает специальные символы.

Например, редактор vi их показывает, а less — нет.

Многие современные текстовые редакторы предусматривают возможность задавать тип разделителей строк, поэтому проверьте, сохраняете ли вы файл в формате, подходящем для вашего Web-сервера.

Если вы пересылаете файлы на свой Web-сервер с помощью FTP, убедитесь в том, что ваш FTP-клиент настроен на пересылку файлов в текстовом (ASCII), а не в двоичном (binary) режиме. Во многих случаях это гарантирует автоматическое преобразование разрывов строк и помогает избежать проблем.

Ошибки доступа к файлам и интерпретатору Perl

Рекомендуем выводить ошибки интерпретатора Perl при тестировании работы скрипта в окно вашего браузера. Для установки данного режима, на время отладки, необходимо вписать в начале скрипта:

use CGI::Carp 'fatalsToBrowser';

Первая строка вашего скрипта должна указывать путь к интерпретатору Perl:

#!/usr/bin/perl

Убедитесь в отсутствии символа возврата каретки (код 0x0D) , в строках скрипта должен быть только символ перевода строки (код 0x0A). Права для CGI скриптов, а также для директории, содержащей скрипты, должны быть выставлены «-rwxr-xr-x», например такой командой:

chmod 755

Синтаксические ошибки

В Perl есть специальное средство, которое позволяет из командной строки проверять программу на наличие синтаксических ошибок, В Unix или Windows (с использованием командного процессора DOS) это делается путем ввода следующей строки на приглашение ОС:

perl -с <ваш_скрипт>.cgi

Независимо от того, какая операционная система используется, при наличии синтаксических ошибок вы получите сообщение с перечнем всех обнаруженных Perl ошибок. Например, сообщение взятое из простой программы, где в конце строки отсутствует закрывающая кавычка:

#can't find string terminator '"' anywhere before EOF
file '<ваш_скрипт>.cgi'; line 3

Получив информацию об ошибках, войдите в программу, сделайте необходимые исправления и продолжайте тестировать программу до тех пор, пока ошибки не исчезнут.

Закончив корректировку, попробуйте запустить программу из командной строки без применения ключа и посмотрите, выдаст ли она правильную стандартную информацию. (Это может быть HTML-страница ошибок, если программа ожидает ввода данных через форму.)

Примечание: Обязательно продолжайте тестирование по этой методике до тех пор, пока Perl не перестанет выдавать сообщения об ошибках. Некоторые ошибки могут скрываться другими; в этом случае Perl сообщит о скрытых ошибках только тогда, когда будут устранены все другие.

Ошибки конфигурации

Программу можно настроить, используя набор переменных конфигурации, которые определяются либо в начале программы, либо в отдельном файле конфигурации. Одни из этих переменных предназначены для конфигурирования опций программы, а другие указывают на местонахождение различных вспомогательных файлов. (Такой подход облегчает настройку поведения программы без внесения изменений в код).

Если переменные, в первую очередь указывающие на внешние файлы, установлены неверно или если они указывают на ресурсы, которые по какой-то причине недоступны, программа генерирует ошибку. При использовании переменных, которые задают файлы, необходимо проверить, существуют ли эти файлы и имеют ли они соответствующие разрешения доступа.

Ошибки формата вывода

Последний тип ошибок, в отсутствии которых нужно убедиться перед вызовом программы из броузера, составляют ошибка формата вывода. Перед всей выходной информацией CGI-программы, предназначенной для Web-броузера посетителя (т.е. перед всем, что выводится в STDOUT), должен идти правильный HTTP-заголовок, иначе будет сгенерирована ошибка «500 Server Error».

Например, если вы генерируете HTML-страницу, то первым выполняемым программой оператором print должен быть следующим:

print "Content-Type: text/html\n\n";

Этот оператор выводит HTTP-заголовок, показывающий, что следующая за ним информация будет содержать HTML-страницу. Если вы не забудете в своей программе поставить эту строку (или соответствующий HTTP-заголовок при выводе не HTML-страницы) перед всеми остальными операторами print, то избежите любых ошибок формата вывода.

Ошибки в логике программы (использование Perl-отладчика)

Если вы проверили программу на наличие ошибок всех категорий, названных в предыдущих разделах, то у вас могут остаться только ошибки, относящиеся к логике программы. Есть два способа выявления такого рода ошибок: использование диагностических сообщений и применение Perl-отладчика.

Запуск отладчика

Если вы используете Perl под Unix или Windows (с командным процессором DOS), то отладчик запускается путем выполнения программы следующим образом:

perl -d program.cgi

Флаг -d дает Perl указание включить отладчик. Вы получите несколько сообщений, за которыми следует приглашение отладчика, выглядящее примерно так:

main::(<ваш_скрипт>.cgi:4): $test_file = "/home/web/test.html";
DB<1>

В верхней строке сообщения отладчика выводится содержимое следующей исполняемой строки. Нижняя строка — это само приглашение; она дает вам знать, что отладчик готов к приему команд.

Как получить помощь

Команды отладчика состоят из одного или двух символов, за которыми иногда следует необязательный или обязательный аргумент.

Полный список этих команд можно получить путем ввода буквы h на приглашении отладчика и нажатия клавиши Enter.

Пошаговое прохождение программы

Основные команды отладчика позволяют обрабатывать программу по одной строке за раз. Если ввести на приглашение отладчика команду s и нажать клавишу Enter, то Perl выполнит следующую строку программы и выдаст новое приглашение.

Если ввести команду n и нажать клавишу Enter, то Perl сделает то же самое, но пропустит вызовы подпрограмм. (Команда s вводит вас в подпрограмму). Если вы использовали любую из этих команд хотя бы один раз, то для повторного ее вызова нужно просто нажать клавишу Enter.

Просмотр значений

В любой момент работы с отладчиком вы можете проверить значения переменных, Для этой цели имеется несколько методов.

Ввод команды X и имени переменной (без спецификатора типа (S, % или @) в начале) и последующее нажатие клавиши Enter заставят Perl выдать список переменных (используемых имя данной переменной) с их значениями в удобном формате. Это позволит вам увидеть содержимое массивов и ассоциативных массивов.

Можно также применить стандартный оператор print, например print $var__name. В принципе, по приглашению отладчика можно использовать любой допустимый оператор языка Perl.

Поиск строк

Если вы уже проследили ошибку до конкретного сегмента программы, то, вероятно, хотите сразу же перейти в эту точку и начать поиск там. Отладчик предоставляет несколько способов перемещения внутри программы. Первый — это использование команды l, которая позволяет отображать номер конкретной строки. Например:

DB<1>  1   180

Эта команда заставит отладчик вывести на экран строку 180. Опустив номер строки, на экран можно вывести группу строк. Можно также вывести диапазон строк:

DB<2>  1   180-200

С помощью команды w можно вывести группу строк с текущей строкой или заданную строку в середине группы, чтобы поместить конкретную строку в контекст:

DB<3>  w 180

Эта команда выводит на экран группу строк со строкой 180 в середине. Если номер строки не указан, то используется номер текущей строки. Второй способ перехода в определенную точку программы — это стандартный поиск по образцу:

DB<4>  \/$count/

Эта команда ищет в программе следующий экземпляр переменной Scount и переходит в строку, которая его содержит. (Закрывающую косую можно опустить).

Точки останова

Если вы не хотите передвигаться по программе пошагово, то, чтобы попасть в нужную строку, можете установить в нее точку останова. Точка останова даст Perl указание выполнить программу до этой строки, затем остановиться и ожидать вашей следующей команды:

DB<5>  b   180

Эта команда заставляет программу сделать паузу, когда она дойдет до строки 180. (Для запуска программы или возобновления ее после прерывания служит команда с). Вы можете также задать условие, которое должно быть выполнено для того, чтобы программа прервалась. Например:

DB<6>  to   180   $count  >   5

Следующая команда заставит программу прерваться на строке 180, если значение переменной Scount больше 5.

Удаление контрольных точек производится с помощью команд d (удаляется одна контрольная точка) и D (удаляются все контрольные точки):

DB<7>   d   180

Выполнение дополнительных команд

Последняя из команд позволяет задавать действие, которое должно быть произведено в указанной строке без прекращения выполнения программы. Например:

DB<8> a 180 print $count;

Эта команда заставит отладчик вывести текущее значение переменной $count непосредственно перед выполнением строки 180.

Отмена действий производится командой А (она отменяет все действия, которые вы установили для программы).

Имитация CGI-вызова

Perl-отладчик можно использовать с CGI-npoграммой. CGI-программы выполняются в удаленном режиме, поэтому доступа к отладчику не имеется. Тем не менее можно сымитировать CGI-вызов из самой программы, с тем чтобы с помощью отладчика следить за проблемами, возникающими только при CGI-вводе.

Установка переменных среды

Если ваша программа использует какие-либо переменные CGI-среды , то вы сможете модифицировать ассоциативный массив %ENV (Такие изменения носят временный характер и действуют на программу только тогда, когда она работает).

Это позволяет ввести в начало программы несколько строк, с помощью которых устанавливаются те переменные среды, которые она использует. Например:

$ENV{'REMOTE_ADDR'} = '100.100.100.100';
$ENV{'REQUEST_METOD'} = 'GET';
$ENV{'QUERY STRING'} = 'name=Myname+ID=123456';

Имитация ввода данных формы

Еще одним элементом, нуждающимся в дублировании при имитации CGI-вызова, являются данные формы, которые передаются в программу. Если для передачи данных в форму используется метод GET, то сделать это достаточно легко. Метод передает данные формы в программу в переменной среды QUERY_STRING, поэтому нужно использовать что-нибудь похожее на две нижние строки приведенного выше примера.

При использовании метода POST ситуация усложняется лишь незначительно. Указанный метод передает в программу данные формы с помощью STDIN и задает количество передаваемых данных с помощью переменной среды CONTENT_LENGTH. Следовательно, для сбора данных можно использовать следующую CGI-программу:

#!/usr/bin/perl
read(STDIN, $buffer, $ENV{'CONTENT__LENGTH'});
open (OUT,">path/to/form_data.txt");
print OUT $buffer;

Эта программа считает данные формы из STDIN, а потом запишет их в  файл. Затем вы должны добавить в свою CGI-программу следующие строки:

$ENV{'REQUEST_METHOD'} = 'POST';
$ENV{'CONTENT_JLENGTH'} = -s '/path/to/form_data.txt';

В переменную среды CONTENT_LENGTH будет занесена информация о числе байтов, содержащихся в файле. Наконец, вы должны вызвать свою программу из командной строки shell следующим образом:

perl -d <ваш_скрипт>.cgi < /path/to/form_data.txt
или
cat /path/to/form_data.txt | perl -d <ваш_скрипт>.cgi

Эти строки превращают запрос POST в запрос GET и считывают содержимое файла данных формы в переменную среды QUERY_STRING.

Как увидеть невидимое

Очень неприятен тот факт, что при выявлении логических ошибок в CGI-программе почти всегда генерируется сообщение «500 Server Error», которое ничего не скажет о происшедшем. Если программа генерирует ошибку «500», а вы не знаете почему, самый простой способ выявить проблему — заставить свой броузер вывести сообщение об ошибке.

Для этого нужно поставить следующие две строки в начало программы (сразу после строки #!/usr/bin/perl:

$| = 1;
print "Content-type:text/plain\n\n";

Первая строка дает Perl указание посылать всю выходную информацию прямо в броузер, не ожидая заполнения буфера. (Благодаря этому мы видим все, что выводит программа, и все, что выводит Perl в процессе выполнения программы).

Вторая строка сообщает броузеру о том, что все выводимое вашей программой в STDOUT должно рассматриваться как обычный текст и отображаться как таковой. Если эта строка есть, то при следующем вызове программы вы должны увидеть сообщение, которое приводит к выдаче сообщения об ошибке «500».

Затем можно войти в программу и устранить проблему или, если вы хотите большего, вставить в программу операторы print, с помощью которых будут выведены диагностические сообщения.

Так, если значение переменной $status должно быть равным 1, а вы подозреваете, что оно будет задано неверно, вставьте в точку, где эта переменная должна быть равной 1, следующую строку:

print "\$status = $status";

При следующем вызове программы вы увидите значение переменной $status у себя в броузере и сможете определить, в нем ли заключается причина возникшей проблемы. (По сути, вы выполняете в дистанционном режиме те же действия, которые обычно производятся в отладчике).

При более сложных ошибках этот метод работает достаточно медленно, но в отличие от других методов он все же работает.

Если ваша программа выполняет несколько функций, а проблема связана только с одной из них, вставьте в начало сегмента, вызывающего эту проблему, строку HTTP — заголовка. Это позволит вам пройти по нормальным сегментам как обычно и настроить все для обработки сегмента с ошибкой.