Spec-Zone.ru › Perl 5.36

perlfaq9

СОДЕРЖАНИЕ

  • НАЗВАНИЕ
  • ВЕРСИЯ
  • ОПИСАНИЕ
    • Стоит ли использовать веб-фреймворк?
    • Какой веб-фреймворк следует использовать?
    • Что такое Plack и PSGI?
    • Как удалить HTML из строки?
    • Как извлечь URL?
    • Как получить файл HTML?
    • Как автоматизировать отправку HTML-формы?
    • Как декодировать или создавать кодировки %-символов в веб-приложении?
    • Как перенаправить на другую страницу?
    • Как добавить защиту паролем к моим веб-страницам?
    • Как убедиться, что пользователи не могут вводить значения в форму, которые могут навредить моему CGI-скрипту?
    • Как разобрать заголовок электронной почты?
    • Как проверить корректность адреса электронной почты?
    • Как декодировать строку MIME/BASE64?
    • Как найти адрес электронной почты пользователя?
    • Как отправить электронную почту?
    • Как использовать MIME для добавления вложений к сообщению электронной почты?
    • Как читать электронную почту?
    • Как узнать имя хоста, имя домена или IP-адрес?
    • Как получить/загрузить файл (S)FTP?
    • Как реализовать удалённый вызов процедур (RPC) в Perl?
  • АВТОР И АВТОРСКИЕ ПРАВА

НАЗВАНИЕ

perlfaq9 - Веб, электронная почта и сетевое программирование

ВЕРСИЯ

версия 5.20210520

ОПИСАНИЕ

Этот раздел посвящён вопросам, связанным с созданием веб-сайтов, отправкой и получением электронной почты, а также общим сетевым задачам.

Стоит ли использовать веб-фреймворк?

Да. Если вы разрабатываете веб-сайт с любой степенью интерактивности (формы, пользователи, базы данных), вам следует использовать фреймворк для упрощения обработки запросов и ответов.

Если интерактивности нет, то вы всё равно можете рассмотреть использование чего-то вроде Template Toolkit или Plack::Middleware::TemplateToolkit, чтобы упростить обслуживание ваших HTML-файлов (и других ресурсов).

Какой веб-фреймворк следует использовать?

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

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

Catalyst

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

Dancer2

Лишён избыточного «веса» наследия, предоставляя лёгкий и простой в изучении API. Обладает растущей экосистемой дополнений. Лучше всего подходит для небольших проектов и очень прост в освоении для начинающих.

Mojolicious

Самодостаточный и мощный для проектов как малого, так и большого масштаба, с акцентом на HTML5 и технологиях реального времени, таких как WebSockets.

Web::Simple

Сильно ориентированный на объекты и минималистичный, созданный для скорости и предназначенный как инструмент для создания микровеб-приложений, пользовательских фреймворков или для объединения существующих совместимых с Plack веб-приложений с одним центральным диспетчером.

Все они взаимодействуют с или используют Plack, освоение основ которого полезно при разработке веб-сайтов на Perl (есть много полезных Plack::Middleware).

Что такое Plack и PSGI?

PSGI — спецификация Perl Web Server Gateway Interface. Это стандарт, используемый многими Perl-веб-фреймворками. Вам не обязательно его понимать для создания веб-сайта, но полезно знать Plack.

Plack — набор инструментов для использования стека PSGI. Он содержит компоненты middleware, демонстрационный сервер и утилиты для веб-приложений. Plack похож на Ruby Rack или Python Paste для WSGI.

Вы могли бы создать веб-сайт с помощью Plack и собственного кода, но для всего, кроме очень простых веб-сайтов, лучше использовать веб-фреймворк (который использует https://plackperl.org).

Как удалить HTML из строки?

Используйте HTML::Strip или HTML::FormatText, которое не только удаляет HTML, но и пытается немного отформатировать полученный простой текст.

Как извлечь URL?

HTML::SimpleLinkExtor извлечёт URL из HTML, обрабатывая якоря, изображения, объекты, фреймы и многие другие теги, которые могут содержать URL. Если вам нужно что-то более сложное, вы можете создать свой собственный подкласс HTML::LinkExtor или HTML::Parser. Вы даже можете использовать HTML::SimpleLinkExtor в качестве примера для чего-то, специально подходящего для ваших нужд.

Вы можете использовать URI::Find или URL::Search для извлечения URL из произвольного текстового документа.

Как получить файл HTML?

(предоставлено brian d foy)

Основной модуль HTTP::Tiny может получать веб-ресурсы и возвращать их содержимое в виде строки:

use HTTP::Tiny;

my $ua = HTTP::Tiny->new;
my $html = $ua->get( "http://www.example.com/index.html" )->{content};

Он также может сохранить ресурс непосредственно в файле:

$ua->mirror( "http://www.example.com/index.html", "foo.html" );

Если вам нужно что-то более сложное, объект HTTP::Tiny можно настроить, задав атрибуты, или вы можете использовать LWP::UserAgent из распределения libwww-perl или Mojo::UserAgent из распределения Mojolicious, чтобы упростить общие задачи. Если вы хотите смоделировать интерактивный веб-браузер, используйте модуль WWW::Mechanize.

Как автоматизировать отправку HTML-формы?

Если вы выполняете сложные действия, такие как проход по многим страницам и формам или по веб-сайту, вы можете использовать WWW::Mechanize. См. его документацию для получения всех подробностей.

Если вы отправляете значения методом GET, создайте URL и закодируйте форму с помощью метода www_form_urlencode из HTTP::Tiny:

use HTTP::Tiny;

my $ua = HTTP::Tiny->new;

my $query = $ua->www_form_urlencode([ q => 'DB_File', lucky => 1 ]);
my $url = "https://metacpan.org/search?$query";
my $content = $ua->get($url)->{content};

Если вы используете метод POST, метод post_form закодирует содержимое соответствующим образом.

use HTTP::Tiny;

my $ua = HTTP::Tiny->new;

my $url = 'https://metacpan.org/search';
my $form = [ q => 'DB_File', lucky => 1 ];
my $content = $ua->post_form($url, $form)->{content};

Как декодировать или создавать кодировки %-символов в веб-приложении?

В большинстве случаев вам это делать не нужно, так как ваш веб-фреймворк или, если вы делаете запрос, модуль LWP или аналогичный модуль сделают это за вас.

Чтобы закодировать строку самостоятельно, используйте модуль URI::Escape. Функция uri_escape возвращает закодированную строку:

my $original = "Colon : Hash # Percent %";

my $escaped = uri_escape( $original );

print "$escaped\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25'

Чтобы декодировать строку, используйте функцию %%%CODE_BLOCK_13%%:

my $unescaped = uri_unescape( $escaped );

print $unescaped; # back to original

Помните, что не нужно кодировать весь URI целиком, вам нужно закодировать каждую компоненту отдельно, а затем объединить их.

Как перенаправить на другую страницу?

Большинство Perl-веб-фреймворков имеют механизм для этого. В фреймворке Catalyst это будет выглядеть так:

$c->res->redirect($url);
$c->detach();

Если вы используете Plack (что делают большинство фреймворков), то Plack::Middleware::Rewrite может быть полезен, если вы мигрируете с Apache или имеете URL, которые нужно всегда перенаправлять.

Как добавить защиту паролем к моим веб-страницам?

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

В качестве альтернативы, рассмотрите Plack::Middleware::Auth::Basic или один из других вариантов аутентификации Plack.

Как убедиться, что пользователи не могут вводить значения в форму, которые могут навредить моему CGI-скрипту?

(предоставлено brian d foy)

Вы не можете предотвратить ввод нежелательных данных в ваш скрипт. Даже если вы добавите проверки на стороне клиента, пользователи могут их отключить или обойти. Например, кто-то может использовать модуль, такой как LWP, для отправки данных вашему веб-сайту. Если вы хотите предотвратить ввод данных, которые могут привести к SQL-инъекциям или другим атакам (а вы должны этого хотеть), вы не должны доверять никаким данным, поступающим в вашу программу.

Документация perlsec содержит общие рекомендации по обеспечению безопасности данных. Если вы используете модуль DBI, используйте подстановки для заполнения данных. Если вы запускаете внешние программы с system или exec, используйте списочные формы. Есть много других мер предосторожности, которые вы должны принять, их слишком много, чтобы перечислить здесь, и большинство из них относятся к тому, чтобы не использовать любые данные, которые вы не намерены использовать. Не доверяйте никому.

Как разобрать заголовок электронной почты?

Используйте модуль Email::MIME. Он хорошо протестирован и поддерживает все сложности реального мира (взаимодействие отступов, кодировки, комментарии и т.д.).

use Email::MIME;

my $message = Email::MIME->new($rfc2822);
my $subject = $message->header('Subject');
my $from    = $message->header('From');

Если у вас уже есть какой-то другой объект электронной почты, рассмотрите возможность передачи его в Email::Abstract, а затем использование метода cast для получения объекта Email::MIME:

my $abstract = Email::Abstract->new($mail_message_object);
my $email_mime_object = $abstract->cast('Email::MIME');

Как проверить корректность адреса электронной почты?

(частично предоставлено Aaron Sherman)

Этот вопрос не так прост, как кажется. Он состоит из двух частей:

a) Как проверить, что адрес электронной почты отформатирован правильно?

b) Как проверить, что адрес электронной почты направлен на действительного получателя?

Без отправки письма на адрес и проверки, есть ли человек на другом конце, который сможет ответить, вы не можете полностью ответить на часть b, но модуль Email::Valid выполнит обе части a и b, насколько это возможно в реальном времени.

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

Связанная стратегия, которая менее уязвима к подделке, – это предоставление ему PIN-кода (персонального идентификационного номера). Запишите адрес и PIN-код (лучше случайный) для дальнейшей обработки. В отправляемом письме укажите ссылку на ваш сайт с включённым PIN-кодом. Если письмо вернётся неотправленным, вы знаете, что адрес недействителен. Если они не перейдут по ссылке, либо адрес был подделан, либо (предполагая, что они получили письмо) выполнение дальнейших действий не было важным, поэтому вы можете не беспокоиться об этом.

Как декодировать строку MIME/BASE64?

Пакет MIME::Base64 обрабатывает это, а также кодировку MIME/QP. Декодирование base 64 становится таким же простым, как:

use MIME::Base64;
my $decoded = decode_base64($encoded);

Модуль Email::MIME может декодировать закодированные base 64 части сообщения электронной почты прозрачно, так что разработчик не должен об этом беспокоиться.

Как найти адрес электронной почты пользователя?

Спросите у него. Существует так много поставщиков электронной почты, что маловероятно, что локальная система знает, как определить адрес электронной почты пользователя.

Исключением являются адреса электронной почты, специфичные для организации (например, foo@yourcompany.com), где политика может быть кодифицирована в вашей программе. В этом случае вы можете обратиться к $ENV{USER}, $ENV{LOGNAME} и получить getpwuid($<) в контексте скалярного значения, как показано ниже:

my $user_name = getpwuid($<)

Однако вы по-прежнему не можете предполагать, что это верно, если ваша политика об этом не говорит. Наиболее надёжный способ – спросить пользователя.

Как отправить электронное письмо?

Используйте модуль Email::Stuffer, например:

# first, create your message
my $message = Email::Stuffer->from('you@example.com')
                            ->to('friend@example.com')
                            ->subject('Happy birthday!')
                            ->text_body("Happy birthday to you!\n");

$message->send_or_die;

По умолчанию Email::Sender::Simple (методы send и send_or_die используют его под капотом) попытается sendmail в первую очередь, если он существует в вашем $PATH. Обычно это не так. Если есть удалённый сервер электронной почты, который вы используете для отправки писем, рассмотрите возможность изучения одного из классов транспорта. На момент написания доступны следующие типы транспорта:

Email::Sender::Transport::Sendmail

Это значение по умолчанию. Если вы можете использовать программу mail(1) или mailx(1) для отправки писем с машины, на которой работает ваш код, вы должны иметь возможность использовать этот вариант.

Email::Sender::Transport::SMTP

Этот транспорт связывается с удалённым SMTP-сервером по TCP. Он необязательно использует TLS или SSL и может аутентифицироваться на сервере через SASL.

Указать Email::Stuffer использовать ваш транспорт очень просто.

$message->transport($email_sender_transport_object)->send_or_die;

Как использовать MIME для добавления вложение к сообщению электронной почты?

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

Email::Stuffer использует Email::MIME под капотом для создания сообщений и обволакивает наиболее распространённые задачи прикрепления вложения с помощью простых методов attach и attach_file.

Email::Stuffer->to('friend@example.com')
              ->subject('The file')
              ->attach_file('stuff.csv')
              ->send_or_die;

Как читать электронные письма?

Используйте модуль Email::Folder, например:

use Email::Folder;

my $folder = Email::Folder->new('/path/to/email/folder');
while(my $message = $folder->next_message) {
  # next_message returns Email::Simple objects, but we want
  # Email::MIME objects as they're more robust
  my $mime = Email::MIME->new($message->as_string);
}

В пространстве имён Email::Folder существуют различные классы для поддержки различных типов почтовых ящиков. Обратите внимание, что эти модули, как правило, довольно ограничены и поддерживают только чтение, а не запись.

Как узнать своё имя хоста, доменное имя или IP-адрес?

(предоставлено brian d foy)

Модуль Net::Domain, который входит в стандартную библиотеку начиная с Perl 5.7.3, может получить для вас полное доменное имя (FQDN), имя хоста или доменное имя.

use Net::Domain qw(hostname hostfqdn hostdomain);

my $host = hostfqdn();

Модуль Sys::Hostname, являющийся частью стандартной библиотеки, также может получить имя хоста:

use Sys::Hostname;

$host = hostname();

Модуль Sys::Hostname::Long использует другой подход и пытается вернуть полное имя хоста:

use Sys::Hostname::Long 'hostname_long';

my $hostname = hostname_long();

Чтобы получить IP-адрес, вы можете использовать встроенную функцию gethostbyname, чтобы преобразовать имя в число. Чтобы преобразовать это число в формат с точкой и октетами (a.b.c.d), который ожидают большинство пользователей, используйте функцию inet_ntoa из модуля Socket, который также входит в состав Perl.

use Socket;

my $address = inet_ntoa(
    scalar gethostbyname( $host || 'localhost' )
);

Как получить/загрузить файл (S)FTP?

Net::FTP и Net::SFTP позволяют взаимодействовать с FTP- и SFTP- (безопасный FTP) серверами.

Как выполнить RPC в Perl?

Используйте один из модулей RPC ( https://metacpan.org/search?q=RPC ).

АВТОР И АВТОРСКИЕ ПРАВА

Авторские права (c) 1997-2010 Tom Christiansen, Nathan Torkington и другие авторы, как указано. Все права защищены.

Эта документация бесплатна; вы можете перераспределять её и/или изменять её на тех же условиях, что и Perl сам по себе.

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

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.36.0/perlfaq9

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API