Perl и HTTP

Perl и HTTP Очень часто многие, кто начинает изучать программирование на языке Perl, сталкиваются с непреодолимым желанием писать сетевые приложения на этом языке. Это дает гибкий и независящий от платформы инструмент для написания простых программ-сценариев для выполнения каких-либо действий в Сети. Один из протоколов, к которому проявляют особый интерес, — это, естественно, HTTP. В этой статье я хочу провести краткий обзор возможностей Perl для работы с этим протоколом.
Сперва отметим, что существует как минимум два способа использования протокола HTTP в языке Perl. Причем первый реализуется на более низком уровне, а второй, соответственно, на более высоком.
В первом случае мы устанавливаем сокетное соединение с HTTP-сервером, после чего, посредством ввода и вывода данных из сокета, мы посылаем запросы HTTP-серверу и получаем результативную страницу, которая может содержать запрошенный документ либо документ, сообщающий об ошибке. Этот метод не столь эффективен для решения простых житейских задач, поскольку требует затраты большего времени и знаний на ее решение. Однако он позволяет контролировать соединение и обмен данными на низком уровне, что предоставляет больше возможностей для программиста. Приведем пример кода, который запросит страницу www.litvinuke.hut.ru/ articles/perlhttp.htm:
#!/usr/bin/perl -w
use IO::Socket;
$host = "www.litvinuke.hut.ru";
$doc = "/articles/perlhttp.htm";
$conn = IO::Socket::INET-> new(Proto => "tcp",
PeerAddr => "$host",
PeerPort => "http(80)");
die "can't connect www.litvinuke.hut.ru" if (!$conn);
$conn-> autoflush(1);
print $remote "GET $doc HTTP/1.0\n\n"; // посылаем запрос
while (<$remote> ) { print; } // читаем данные из сокета и выводим их на STDOUT
close $remote;
В этом примере наглядно иллюстрируется работа с сокетами с использованием класса IO::Socket. Не будем останавливаться на этом методе и в частности на этом примере. Я думаю, здесь все ясно. Если же вы хотите узнать больше о программировании сокетов, то по этой теме существует множество литературы, которая более чем подробно освещает эту проблему.
Что касается второго метода, то он заключается в использовании дополнительных специализированных библиотек/пакетов. Приведу для начала пример, который будет выполнять практически те же функции, что и пример, приведенный выше, только в соответствии со вторым способом, т.е. с использованием специальных пакетов.
#!/usr/bin/perl -w
use LWP::UserAgent;
use HTTP::Request;

$url = "http://www.litvinuke. hut.ru/articles/perlhttp.htm";

$lwp = LWP::UserAgent-> new;
$r = HTTP::Request-> new(GET => "$url");
$response = $lwp-> request($r);
if ($response-> is_success)
{
print $response-> content;
}
else
{
print $response-> error_as_HTML;
}
Как видно из вышеприведенного кода, мы используем два новых класса: LWP::UserAgent и HTTP::Request. Теперь вместо того, чтобы указывать адрес и путь к документу по отдельности, мы используем URL, благодаря чему одним указанием URL к документу можно задать пароль и имя пользователя, если они необходимы. После этого, создав объекты, мы запрашиваем указанный документ, и при помощи метода request класса LWP::UserAgent выполняем HTTP-запрос $r. Если данные получены, то выводим их на STDOUT.
HTTP::Request — это класс, инкапсулирующий стиль HTTP-запросов, состав строки запроса (URL), заголовки и кое-что еще. LWP::UserAgent используется не только для осуществления HTTP-запросов, но в нашем контексте мы будем рассматривать лишь их. Чтобы выполнить/послать запрос, мы выполняем следующие действия:
$lwp = LWP::UserAgent-> new; # создаем объект $lwp класса LWP::UserAgent
$request = HTTP::Request-> (
GET => "http://www.litvinuke. hut.ru/articles/perlhttp.htm"); # создаем новый объект-запрос
$response = $lwp-> request ($request); # пытаемся выполнить запрос $request
HTTP::Request является классом- потомком класса HTTP::Message и наследует все его поля и методы, самые распространенные (используемые) из которых: header(), push_header(), remove_header(), content(). Описание этих методов можно посмотреть в документации, поставляемой с вашей версией Perl.
Сначала рассмотрим параметры, которые принимает конструктор класса HTTP::Request:
HTTP::Request-> new($Method, $Uri, [$header, [$content]]);
Думаю, если сопоставить с примером, то проблем с пониманием значения первых двух параметров возникнуть не должно. Вторые использовать не обязательно, плюс к тому они должны быть ссылками на объект класса HTTP::Header.
При отладке вашей программы может пригодиться метод класса HTTP::Request as_string(), который представляет объект запроса в виде строки, что дает возможность разобраться в неправильной логике программы, если в программе присутствуют ошибки.
Но класс HTTP::Request, как уже было сказано выше, всего лишь инкапсулирует правила создания HTTP-запросов, а основную работу по транспортировке данных выполняет экземпляр класса LWP::UserAgent.
Конструктор этого класса не принимает никаких параметров, поэтому перечислю некоторые важные и не затрагиваемые нами методы этого класса (параметры, заключенные в квадратные скобки, не являются обязательными и могут быть опущены):
from([$email]) — возвращает/устанавливает электронный адрес человека, который выполняет запрос; по умолчанию значения нет. Пример:
$lwp-> from('litvinuke@tut.by');
timeout([$seconds]) — возвращает/устанавливает значение времени ожидания ответа на запрос удаленным сервером; по умолчанию 180 секунд.
cookie-jar([$cookies]) — возвращает/устанавливает объект класса HTTP::Cookie для использования во время запроса; это очень полезный метод, с его помощью без труда можно запрашивать страницы, которые записывают идентификационную информацию в cookie.
max-size([$bytes]) — возвращает/устанавливает максимальный размер ответа сервера (получаемого документа); по умолчанию ограничение на размер снято.
proxy(...) — чрезвычайно полезный для многих метод, определяет параметры для работы через прокси:
$lwp-> proxy(['http','ftp'], 'http://proxy.server. url.by:8081/');
no_proxy($domain, ...) — запрещает использование прокси для перечисленных адресов:
$lwp-> no_proxy('localhost', 'litvinuke.hut.ru');
Эти методы значительно расширяют возможности по осуществлению HTTP-запросов в Perl. За более подробной информацией по этой теме вы можете обратиться к документации по Perl или посмотреть что-нибудь на www.perl.com. На этом все — пишите.
Алексей Литвинюк


Компьютерная газета. Статья была опубликована в номере 17 за 2002 год в рубрике программирование :: разное

©1997-2024 Компьютерная газета