perlfaq9
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- ВЕРСИЯ
- ОПИСАНИЕ
- Использовать ли веб-фреймворк?
- Какой веб-фреймворк использовать?
- Что такое Plack и PSGI?
- Как удалить HTML из строки?
- Как извлечь URL-адреса?
- Как получить HTML-файл?
- Как автоматизировать отправку HTML-формы?
- Как декодировать или создавать %-кодировки в веб-приложении?
- Как перенаправить на другую страницу?
- Как добавить пароль на мои веб-страницы?
- Как убедиться, что пользователи не могут вводить значения в форму, которые могут привести к нежелательным действиям скрипта CGI?
- Как разобрать заголовок письма?
- Как проверить корректность адреса электронной почты?
- Как декодировать строку MIME/BASE64?
- Как найти адрес электронной почты пользователя?
- Как отправить электронное письмо?
- Как использовать MIME для добавления вложений к сообщению электронной почты?
- Как читать электронную почту?
- Как узнать имя хоста, домен или IP-адрес?
- Как получить/загрузить файл (S)FTP?
- Как реализовать RPC в Perl?
- АВТОР И АВТОРСКИЕ ПРАВА
НАЗВАНИЕ
perlfaq9 - Веб, электронная почта и сети
ВЕРСИЯ
версия 5.021011
ОПИСАНИЕ
Этот раздел посвящен вопросам, связанным с запуском веб-сайтов, отправкой и получением электронной почты, а также общим вопросам работы в сети.
Использовать ли веб-фреймворк?
Да. Если вы создаете веб-сайт с каким-либо уровнем интерактивности (формы/пользователи/базы данных), вам следует использовать фреймворк для упрощения обработки запросов и ответов.
Если интерактивности нет, то вы все равно можете рассмотреть использование чего-то вроде Template Toolkit или Plack::Middleware::TemplateToolkit, чтобы упростить обслуживание файлов HTML (и других ресурсов).
Какой веб-фреймворк использовать?
На этот вопрос нет простого ответа. Perl-фреймворки могут обрабатывать все, от простых файловых серверов и небольших интрасетей до масштабных многонациональных многоязычных веб-сайтов, которые являются основой международных бизнесов.
Ниже приведен список нескольких фреймворков с комментариями, которые могут помочь вам принять решение в зависимости от ваших конкретных потребностей. Начните с чтения документации, затем задавайте вопросы на соответствующих почтовых списках или каналах IRC.
- Catalyst
-
Сильно ориентированный на объекты и полнофункциональный фреймворк с богатой историей разработки, большим сообществом и экосистемой дополнений. Он отлично подходит для больших и сложных приложений, где вы имеете полный контроль над сервером.
- Dancer
-
Молодой и лишенный избыточного кода, обеспечивая легкий и простой в освоении 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's Rack или Python's Paste для WSGI.
Вы могли бы создать веб-сайт с помощью Plack и собственного кода, но для всего, кроме очень простого веб-сайта, использование веб-фреймворка (который использует Plack) — лучший вариант.
Как удалить HTML из строки?
Используйте HTML::Strip или HTML::FormatText, который не только удаляет HTML, но и пытается немного отформатировать полученный обычный текст.
Как извлечь URL-адреса?
HTML::SimpleLinkExtor извлечёт URL-адреса из HTML, обрабатывая анкоры, изображения, объекты, фреймы и многие другие теги, которые могут содержать URL. Если вам нужно что-то более сложное, вы можете создать собственный подкласс HTML::LinkExtor или HTML::Parser. Возможно, вы даже можете использовать HTML::SimpleLinkExtor в качестве примера для чего-то, специально подходящего для ваших нужд.
Вы можете использовать URI::Find для извлечения URL-адресов из произвольного текстового документа.
Как получить HTML-файл?
(внесён brian d foy)
Используйте дистрибутив libwww-perl. Модуль LWP::Simple может получать веб-ресурсы и возвращать их содержимое в виде строки:
use LWP::Simple qw(get);
my $html = get( "http://www.example.com/index.html" ); Он также может сохранить ресурс непосредственно в файле:
use LWP::Simple qw(getstore);
getstore( "http://www.example.com/index.html", "foo.html" ); Если вам нужно сделать что-то более сложное, вы можете использовать модуль LWP::UserAgent для создания собственного пользовательского агента (например, браузера), чтобы выполнить задачу. Если вы хотите смоделировать интерактивный веб-браузер, вы можете использовать модуль WWW::Mechanize.
Как автоматизировать отправку HTML-формы?
Если вы делаете что-то сложное, например, проход по многим страницам и формам или по сайту, вы можете использовать WWW::Mechanize. Обратитесь к его документации для получения всех деталей.
Если вы отправляете значения с помощью метода GET, создайте URL-адрес и закодируйте форму с помощью query_form метода:
use LWP::Simple;
use URI::URL;
my $url = url('L<http://www.perl.com/cgi-bin/cpan_mod')>;
$url->query_form(module => 'DB_File', readme => 1);
$content = get($url); Если вы используете метод POST, создайте собственный пользовательский агент и закодируйте содержимое соответствующим образом.
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $req = POST 'L<http://www.perl.com/cgi-bin/cpan_mod'>,
[ module => 'DB_File', readme => 1 ];
my $content = $ua->request($req)->as_string; Как декодировать или создавать %-кодировки в веб-приложении?
В большинстве случаев вам не нужно этого делать, поскольку ваш веб-фреймворк или, если вы выполняете запрос, модуль 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' Для декодирования строки используйте функцию uri_unescape:
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, а затем использование его метода преобразования для получения объекта Email::MIME:
my $mail_message_object = read_message();
my $abstract = Email::Abstract->new($mail_message_object);
my $email_mime_object = $abstract->cast('Email::MIME'); Как проверить действительность адреса электронной почты?
(частично предоставлено Аароном Шерманом)
Это не такой простой вопрос, как может показаться. Есть две части:
a) Как проверить, что адрес электронной почты отформатирован правильно?
b) Как проверить, что адрес электронной почты направлен на действительного получателя?
Без отправки письма по адресу и проверки, есть ли человек на другом конце, который вам ответит, вы не можете полностью ответить на часть b, но модуль Email::Valid выполнит и часть a, и часть b, насколько это возможно в реальном времени.
Лучший совет по проверке адреса электронной почты человека — попросить его дважды ввести свой адрес, как обычно при смене пароля. Это обычно помогает выявить опечатки. Если обе версии совпадают, отправьте письмо по этому адресу с личным сообщением. Если вы получите письмо обратно и он выполнил ваши инструкции, можно с уверенностью сказать, что адрес действителен.
Связанная стратегия, которая менее подвержена подделке, — предоставить им PIN-код (личный идентификационный номер). Запишите адрес и PIN-код (желательно случайный) для последующей обработки. В отправляемом письме включите ссылку на ваш сайт с указанным PIN-кодом. Если письмо вернулось, вы знаете, что адрес недействителен. Если они не перейдут по ссылке, либо адрес был подделан, либо (предполагая, что они получили письмо) его прохождение не было важным, поэтому об этом можно не беспокоиться.
Как декодировать строку MIME/BASE64?
Пакет MIME::Base64 обрабатывает это, а также кодировку MIME/QP. Декодирование base64 становится таким простым, как:
use MIME::Base64;
my $decoded = decode_base64($encoded); Модуль Email::MIME может прозрачно декодировать части сообщения электронной почты, закодированные в base64, поэтому разработчик не должен об этом беспокоиться.
Как найти адрес электронной почты пользователя?
Спросите у него. Существует множество доступных провайдеров электронной почты, поэтому маловероятно, что локальная система знает, как определить адрес электронной почты пользователя.
Исключением является организационная электронная почта (например, foo@yourcompany.com), где политика может быть кодифицирована в вашей программе. В этом случае вы можете посмотреть на $ENV{USER}, $ENV{LOGNAME} и получить getpwuid($<) в контексте скаляра, как показано ниже:
my $user_name = getpwuid($<) Но вы по-прежнему не можете сделать предположений о том, правильно ли это, если ваша политика этого не утверждает. На самом деле вам лучше всего спросить у пользователя.
Как отправить электронное письмо?
Используйте модули Email::MIME и Email::Sender::Simple, как показано ниже:
# first, create your message
my $message = Email::MIME->create(
header_str => [
From => 'you@example.com',
To => 'friend@example.com',
Subject => 'Happy birthday!',
],
attributes => {
encoding => 'quoted-printable',
charset => 'utf-8',
},
body_str => "Happy birthday to you!\n",
);
use Email::Sender::Simple qw(sendmail);
sendmail($message); По умолчанию модуль Email::Sender::Simple сначала попытается использовать `sendmail`, если он существует в вашем $PATH. Это обычно не так. Если есть удаленный сервер электронной почты, который вы используете для отправки писем, изучите один из классов транспорта. На момент написания доступные транспорты включают:
- Email::Sender::Transport::Sendmail
-
Это значение по умолчанию. Если вы можете использовать программу mail(1) или mailx(1) для отправки писем с машины, на которой выполняется ваш код, вы должны иметь возможность использовать этот метод.
- Email::Sender::Transport::SMTP
-
Этот транспорт связывается с удаленным SMTP-сервером по протоколу TCP. Он необязательно использует SSL и может аутентифицироваться на сервере с помощью SASL.
- Email::Sender::Transport::SMTP::TLS
-
Это аналогично транспорту SMTP, но использует безопасность TLS. Вы также можете аутентифицироваться с помощью этого модуля, используя любые механизмы, поддерживаемые вашим сервером после STARTTLS.
Указать Email::Sender::Simple использовать ваш транспорт просто.
sendmail(
$message,
{
transport => $email_sender_transport_object,
}
); Как использовать MIME для добавления вложения к сообщению электронной почты?
Email::MIME напрямую поддерживает сообщения multipart. Объекты Email::MIME сами являются частями и могут быть добавлены в качестве вложений к другим объектам Email::MIME. Для получения дополнительной информации, включая все поддерживаемые методы и примеры их использования, см. документацию Email::MIME.
Как читать электронную почту?
Используйте модуль 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-адрес?
(предоставлено Брайаном Д. Фоем)
Модуль 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 Тома Кристиансена, Натана Торкинтона и других авторов, как указано. Все права защищены.
Данная документация является бесплатной; вы можете перераспределять и/или изменять ее в соответствии с теми же условиями, что и Perl сам по себе.
Независимо от его распространения, все примеры кода в этом файле объявляются общедоступными. Вы можете и должны использовать этот код в своих программах для развлечения или получения прибыли по своему усмотрению. Простой комментарий, дающий зачёт, был бы вежливым, но не обязательным.
© 1993–2020 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.28.3/perlfaq9