Получение почты
Получение почты
Обсуждая в этом разделе получение почты, мы не будем говорить о ее сборе (fetching). Передача почты с одной машины на другую не представляет особого интереса. Модули Mail: :POP3Client Сина Дауда (Sean Dowd) и Mail: :Cclient Малколма Битти (Malcolm Beattie) легко могут передать почту по протоколам POP (Post Office Protocol) или ШАР (Internet Message Access Protocol). Гораздо интереснее посмотреть, что с этой почтой делать после ее получения, и именно на этом мы и остановимся.
Начать следует с основ, поэтому рассмотрим инструменты, позволяющие разбить как отдельные сообщения, так и почтовые ящики. Чтобы рассмотреть первое, вновь обратимся к пакету MailTools Грэма Бара (Graham Barr), на этот раз прибегнем к модулям Mail : :Interne: и Mail : :Header.
Разбиение отдельных сообщений
Модули Mail: :Internet и Mail: :Header предлагают удобный способ разбить заголовки почтового сообщения, соответствующего RFC822. RFC822 определяет формат почтового сообщения, включая имена допустимых заголовков и их форматов.
Модулю Mail: : Internet необходимо передать либо файловый дескриптор файла с сообщением, либо ссылку на массив, содержащий его строки:
use Hail::Internet: $messagefile = "mail";
open(MESSAGE,"Smessagefile") or die "Невозможно открыть $messagefile:$!\n";
Smessage = new Mail::Internet VMESSAGE;
close(MESSAGE);
Если мы хотим анализировать сообщение, поступающее в стандартный поток ввода (т. е. переданное через конвейер на стандартный ввод), можно поступить так:
use Mail::Internet;
Smessage = new Mail: :Internet VSTDIN;
Mail: : Internet возвращает экземпляр объекта сообщения. Чаще всего с этим экземпляром объекта будет применяться один из двух методов: body() и head(). Метод body() возвращает ссылку на анонимный массив, содержащий строки тела сообщения. head() более интересен и предлагает плавное продолжение модуля Mail: : Header.
При загрузке Mail::Internet неявно загружается Mail::Header. Если вызвать метод head() модуля Mail: :Internet, он вернет экземпляр объекта заголовка Mail: :Header. Это будет тот же экземпляр объекта, который можно получить, если использовать не Mail: :Internet, а напрямую Mail: :Header:
use Mail::Header; Smessagefile = "mail";
open(MESSAGE,"Smessagefile") or die "Невозможно открыть $messagefile:$!\n"
$header = new Mail:: Header VMESSAGE;
close(MESSAGE):
Объект $header содержит заголовки сообщения и предлагает несколько удобных способов для получения данных. Например, чтобы вывести отсортированный список встречающихся имен заголовков (которые в модуле называются «тегами»), можно добавить такую строчку в конец предыдущего примера:
print join("\n",sort $header->tags);
В зависимости от сообщения можно увидеть что-то подобное нижеследующему:
Сс
Date
From
Message-Id
Organization
Received
Reply-To
Sender
Subject
To
Необходимо получить все заголовки Received: из сообщения. Вот как это можно сделать:
received = $header->get("Received");
Часто методы Mail: :Header используются вместе с объектом Mail: : Internet. Если применять Mail: : Internet для возвращения объекта, содержащего и тело и заголовки сообщения, можно сцепить вместе некоторые методы из этих модулей:
©received = $message->head->get("Received"):
Обратите внимание, что get()вызывается в списочном контексте. В скалярном контексте метод вернул бы только первое вхождение этого тега, в случае, если бы мы не задали вторым аргументом порядковый номер тега. Например, get("Received", 2) вернет вторую строку Receivec: из сообщения. Модуль Mail: : Header предоставляет и другие методы для удаления и добавления тегов в заголовки; подробную информацию можно найти в документации.