Построение
Web-сайта
После того, как Web-сервер
сконфигурирован и отлажен, создадим для примера небольшой Web-сайт, чтобы показать,
как развертывать информацию в Web.
Построим сайт, который
будет содержать информацию о небольшой издательской компании On The Web Publishers.
Разместим на сайте список новых изданий, общую информацию об издателе, форму
для контактов и защищенный паролем раздел для эксклюзивного использования авторами,
имеющим контракт с издателем.
В рамках поставленной задачи
попытаемся создать сайт, содержащий HTmL-документы и изображения, использующий
CGi-программирование и выполняющий контроль доступа защищенного паролем раздела
на сайте.
Определим структуру сайта,
как показано на рис. 32.2.
Рис. 32.2.
Структура Web-сайта
Создадим файлы, необходимые
для реализации этой структуры. Подразумевая использование конфигурации, рассмотренной
ранее в главе, поместим корневой каталог для дерева HTmL-документов в /var /www/html,
а каталог CGi - в /var /www/cgi-bin. Дерево каталогов и файлов:
/var/www/html/index.html
/var/www/html/about/index.html
/var/www/html/books/index.html
/var/www/html/contact/index.html
/var/www/html/authors/index.html
/var/www/cgi-bin/formmail
Кроме последнего файла,
который мы рассмотрим вкратце, все перечисленные файлы являются HTmL-файлами.
Все вспомогательные файлы с изображениями, используемые HTmL-файлами, можно
разместить в тех же каталогах, что и файлы HTmL. Многие Web-мастера предпочитают
размешать все файлы с изображениями в другом каталоге. Этот каталог может быть
следующим.
/var/www/html/images/
Так как в главе не рассматривался
язык HTmL, оценим два HTmL-файла в качестве примеров соответствующих документов.
Начнем с главной домашней странички /var/www/html/ index. html. В данном случае
исходный текст файла может быть следующим.
<HTmL>
<HEAD>
<TiTLE>On
the Web Publishers</TiTLE>
</HEAD>
<bODY bGCOLOR=lightcyan
TEXT=midnightblue>
<DiV ALiGN=CENTER>
<A HREf="/">
<imG SRC="/images/logo.gif" bORDER=0></A>
<TAbLE bORDER=0
CELLPADDiNG=5 CELLSPACiNG=5
bGCOLOR=1ightp
ink> <TR>
<TD ALiGN=CENTER><A
HREf="about">Ab00T U</A></TD>
<TD ALiGN=CENTER><A
HREf="books">OUR
bOOKS</A></TD>
<TD ALiGN=CENTER><A
HREf="contact">CONTACT
US</A></TD>
<TD ALiGN=CENTER><A HREf="authors">JUST fOR
AUTHORS</A></TD>
</TR> </TAbLE>
</DiV>
<fONT SiZE=5>W</f>elcome to <STRONG>On the Web Publishers</STRONG>.
We offer the finest
in on-line electronic books at .reasonable prices. Check out what we have to
offer ...
<UL>.
<Li><A
HREf="about">Learn about what we do</A>
<Li><A
HREf="books">See what books we offer</A>
<Li><A
HREf="contact">Contact us</A>
</UL>
</bODY>
</HTmL>
Результат работы этого
файла показан на рис. 32.3.
Рис. 32.3.
Домашняя страница
Остальные страницы будут
выглядеть примерно так же, кроме формы для контактов /var/ www/html/contact/index.html.
Форма для контактов показана на рис. 32.4, она реализуется следующим исходным
кодом.
<HTmL>
<TiTLE>On
the Web Publishers</TiTLE> </HEAD>
<bODY bGCOLOR=lightcyan
TEXT=midnightblue>
<DiV ALiGN=CENTER>
<A HREf="/">
<imG SRC="/images/ldgo.gif" bORDER=0></A>
<TAbLE bORDER=0
CELLPADDiNG=5 CELLSPACiNG=5
bGCOLOR= 1 ightp
ink> <TR>
<TD ALiGN=CENTER><A
HREf="/about">AbOUT
US</A></TD>
<TD ALiGN=CENTER><A
HREf="/books">OUR
bOOKS</A></TD>
<TD ALiGN=CENTER
bGCOLOR=yellow>CONTACT
US</TD>
<TD ALiGN=CENTER><A HREf="/authors">JUST fOR
AUTHORS</A></TD>
</TR> </TAbLE>
<Hl>Drop
Us A Line ...</H1> </DiV>
<TAbLE ALiGN=CENTER><TR><TD>
<fORm mETHOD=POST
ACTiON="/cgi-bin/formmail">
<iNPUT TYPE=TEXT
WiDTH=30 NAmE=name> Name<bR>
<iNPUT TYPE=TEXT
WiDTH=30 NAmE=address> Address<bR>
<iNPUT TYPE=TEXT WiDTH=30 NAmE=city> City<bR>
<iNPUT TYPE=TEXT WiDTH=30 NAmE=state> State<bR>
<iNPUT TYPE=TEXT WiDTH=30 NAmE=zip> Zip/Post Code<bR>
<iNPUT TYPE=TEXT WiDTH=30 NAmE=country> Country<bR>
<iNPUT TYPE=TEXT WiDTH=30 NAmE=email> E-mail<bR>
Comments:<bR>
<TEXTAREA ROWS=10 COLS=30 NAmE=commentS WRAP=HARD></TEXTAREA><bR>
<iNPUT TYPE=SUbmiT
VALUE="Send Comments"> </fORm> </TD></TR></TAbLE>
</bODY>
</HTmL>
Рис. 32.4.
Форма для контрактов
Эта страница содержит форму
и ссылку на CGi-программу, которая обрабатывает данные из формы. В нашем случае
используется программа f ormmail (бесплатно распространяемый сценарий CGi, написанный
на Perl), которая считывает содержимое формы и отправляет его по почте на предопределенный
почтовый адрес. В рассматриваемом примере контактная информация из формы отправляется
по почте на главный почтовый адрес книжного магазина.
forramail написал matthew
m. Wright. Эта программа доступна по адресу http: / /www. worldwideniart.com/scripts/formmail
.shtml. Несмотря на то, что в главе не затрагивалось программирование на Perl
и CGi, мы приводим исходный код программы. Можно заметить, что создание несложных
CGi-программ не требует особых усилий.
#!/usr/bin/perl
################################
# fonrimail Version
1.6 #
# Copyright 1995-1997
matt Wright mattw@worldwidemart.com #
# Created 06/09/95
Last modified 05/02/97 #
# matt's Script Archive, inc.: http://www.worldwidemart.com/scripts/
######################################
# COPYRiGHT NOTiCE #
#Copyright 1995-1997
matthew m. Wright All Rights Reserved. #
# #
# formmail может
быть использована и свободно модифицирована любым
# пользователем, при условии сохранности авторских прав и
# комментариев,
приведенных выше. Используя этот код, вы
# соглашаетесь
не требовать от автора возмещения убытков при любых
# обстоятельствах,
которые могут возникнуть при ее использовании.
#
# Продажа кода
этой программы без предварительного письменного согласия
# категорически
запрещена. Прежде чем получить деньги за мою программу,
# спросите меня.
#
# Получите разрешение
перед распространением этого программного
# обеспечения
в пределах internet и любого другого окружения. Во всех
# случаях знаки авторского права и заголовок должны быть сохранены
######################################
# Определение
переменных #
# Более подробную
информацию можно найти в файле READmE. #
# $mailprog определяет
местонахождение программы sendmail в системе unix. #
$mailprog = Vusr/lib/sendmail';
# @referers разрешает
формам находиться только на серверах, определенных
# в этом поле.
Это корректировка безопасности по сравнению с предыдущей
# версией, которая
позволяла любому пользователю на любом сервере
# использовать
сценарий formmail на своем Web-сайте.
# referers = Clinux.juxta.com');
# Конец
######################################
# Проверка ссылающегося
URL &check_url;
# Получить дату
&get_date ;
# Разобрать содержимое
формы &parse_form;
# Проверить обязательные
поля &check_required;
# Возвратить HTmL-страницу
или перенаправить пользователя &return_html ;
# Послать E-mail
&send_mail;
sub check_url
{
# Локализировать
флаг check_referer, который определяет,
# является ли
пользователь допустимым. local ($check_referer) = 0;
# Если был- указан
URL рекомендателя, убедиться, что для каждого
# допустимого
рекомендателя в formmail передан правильный URL.
if ($ENV{'HTTP_REfERER'})
{
foreach $referer
(Oreferers) {
if ($ENV{toTP_REfERER'}
=~ m|https? : // ( [^/] *) $referer | i) {
last;
} } }
else {
$check_referer
= 1;
}
# Если HTTP_REfERER
был недопустимым, возвратить ошибку.
if ($check_referer
!= 1) { &error <bad_referer') }
}
sub get_date {
# Определить массивы для дней недели и месяцев года.
@days = ('Sunday','monday','Tuesday','Wednesday',
'Thursday', 'friday',
'Saturday') ;
@months = ('January','february',"march','April',
'may','June','July', 'August','September', 'October','November','December')
;
# Получить текущее время и формат часов, минут и секунд. Добавить
# 1900 к году,
чтобы получить полный 4-цифровой год.
($sec,$min,$hour,$mday,$mon,$year, $wday) = (localtime(time))[0,1,2,3,4,5,6];
$time = sprintf
("%02d:%02d:%02d", $hour, $min, $sec) ; $year += 1900;
# Сформатировать
дату.
$date = "$days[$wday],
$months[$mon] $mday, $year at $time";
}
sub parse_form
{
# Определить ассоциативный массив для конфигурации
# Config = ('recipient',",
'subject',",
'email',",
'realname', ",
'redirect
1
,'
1
,
'bgсоlоr', ",
'background',",
'link_color',",
'vlink_color',
' ', 'text_color', ' ',
'alink_color',",
'title',",
'sort', ' ', 'print_conf
ig', ' ',
'required' , "
, 'eny_report' , " ,
'return_link_title',
' ', 'return_link_url', ' ',
'print_blank_f
ields
1
, ' ', 'missing_f ields_redirect', ") ;
# Определить для
формы REQUEST_mETHOD (GET или POST) и распределить
# поля формы по
парам имя-значение. Если REQUEST_mETHOD не был ни
# GET, ни POST,
выдать ошибку.
if ($ENV{'REQUEST_mETHOD'}
eg 'GET') {
# Разложить по
парам имя-значение @pairs = split (/&/, $ENV{'QUERY_STRiNG'} ) ;
}
elsif ($ENV{'REQUEST_mETHOD'}
eg 'POST') {
# Считать входную
информацию read(STDiN, $buffer, $ENV{'CONTENT_LENGTH'} ) ;
# Разложить по
парам имя-значение
Opairs = split
(/&/, $buf fer) ; } else {
&error ('request_method')
;
}
# Для каждой пары
имя-значение
foreach $pair
(Opairs) {
# Разложить пару
по отдельным переменным local($name, $value) = split(/=/, $pair) ;
# Декодировать кодировку формы для переменных имени и значения
$name =~ tr/+/
/ ;
$name =~ s/% (
[a-fA-fO-9] [a-fA-fO-9] ) /packC'c", hex($l) ) /eg;
$value =~ tr/+/
/;
$value =~ s/%
( [a-fA-fO-9] [a-fA-fO-9] )/pack("C", hex($l) ) /eg;
# Если они пытаются
использовать включения со стороны сервера,
# удалить их,
чтобы они не были угрозой безопасности, если html
# будет возвращен. Еще одна брешь в защите перекрыта.
$value =~ s/<!-(
. |\n)*->//g;
# Если имя поля
указано в массиве %Config, по вызову
# defined ($Config{$name)
}) будет возвращена 1 и нам нужно связать
# это значение
с соответствующей переменной конфигурации. Если же
# это не конфигурационное
поле формы, записать его в ассоциативный
# массив %form,
добавив перед значением ', ', если там уже есть
# какое-то значение.
Также сохраним порядок полей формы в массиве
# @field_Order,
чтобы можно было использовать этот порядок при
# обычной сортировке.
if (defined($Config{$name)))
{ $Conf ig{$name) = $value,-
else {
if ($form{$name)
&& $value) {
$form{$name) =
"$form{$name} , $'value";
elsif ($value)
{
push(@field_Order,$name);
$form{$name} = $value;
} }
# Последующие
шесть строчек удаляют лишние пробелы и символы перевода
# строки из переменных
конфигурации, которые могут появиться в случае,
# если редактор
переносит строки после некоторой длины строки или если
# были использованы пробелы между именами полей или переменными среды.
$Config{'required'} =- s/ (\s+|\n)?,(\s+|\n)?/,/g;
$Config{'required'} =- s/ (\s+) ?\n+ (\s+) ?//g;
$Config{'env_report'} =- s/ (\s+ | \n) ?, (\s+ | \n) ?/ , /g;
$C6n£ig{'env_repO3rt'}
=-
s/
(\s+)
?\n+ ( \s-i-)
?
//g;
$Config{'print_config'} =- s/ (\s+| \n) ?, (\s+| \n) ?/, /g;
$Config{'print_config'}
=- s/ (\s+) ?\n+ (\s+) ?,
# Разложить переменные конфигурации по отдельным именам полей.
@Reguired = split
(/, / , $Conf ig{ 'required'} ) ;
@Env_Report = split ( / , / , $Conf ig{'env_report'} ) ;
@Print_Config =
split (/,/, $Conf ig{'print_conf ig'} ); }
sub check_required
{
# Локализация переменных, используемых в этой подпрограмме.
local ($require,
@error) ;
if ( !$Config{
'recipient '}) {
if (!defined (%form)
) { &error (bad_referer') } else { kerror ('no_recipient') }
# Для каждого обязательного поля, определенного в форме:
foreach $require
(@Required) {
# Если обязательное
поле является email, проверить синтаксис email
# адреса, чтобы
убедиться в его правильности.
if ($require eq
'email' && !&check_email ($Conf ig{$require} ) ) { /push ( ©error
, $require) ;
}
# Иначе, если
обязательное поле является полем конфигурации и не
# указано его значение или заполнено пробелами, выдать ошибку.
elsif (def ined($Config{$require}
) ) { if ( !$Config{$require) ) { push (@error , $require) ;
# Если обычное
поле формы не заполнено или заполнено пробелами,
# отметить его как ошибочное поле .
elsif ( !$form{$require})
{
push(@error,$require)
;
# Если найдено
хотя бы одно ошибочное поле, послать пользователю
# сообщение об
ошибке .
if (@error) {
&error('missing_fields',@error) }
sub return_html
{
# Инициализировать
локальные переменные,
# используемые
этой подпрограммой.
local ($key, $sort_order
, $sorted_field) ;
# Если используется
опция переадресации, напечатать заголовок
# с адресом переадресации.
if ($Config{'redirect'}>
{
print "Location:
$Config{'redirect'} \n\n";
# Иначе, начать
печать страницу ответа.
else {
# Напечатать заголовок HTTP и открывающие дескрипторы HTTP.,
print "Content
-type: text/html \n\n";
print "<html>\n
<head>\n";
# Напечатать заголовок
страницы
if ($Config{'title'})
{ print " <title>$Conf ig{'title'}</title>\n" } else {
print " <title>Cnacибо</title>\n" } print " </head>\n
<body>;
# Получить атрибуты
дескриптора body &body_attributes ;
# Закрыть дескриптор
body print ">\n <center>\n";
# Напечатать специальный
или общий заголовок.
if ($Config{'title'})
{ print " <hl>$Conf ig{'title'}</hl>\n" }
else { print "
<h1>Спасибо Вам за заполнение данной формы</h1>\n" }
print "</center>\n";
print "Ниже находится предоставленная вами информация для ";
print "$Conf ig{'recipient'} . Текущая дата: ";
print "$date<pxhr
size=l width=75\%><p>\n";
# Если указано, отсортировать по алфавиту:
if ($Config{'sort'}
eq 'alphabetic') { foreach $ field (sort keys %form) {
# Если поле имеет
значение или установлена опция печати пустых
# полей, то распечатать поле формы и его значение.
if ($Config{'print_blank_f
ields'} || ?form{$field}) {
print "<b>$field:</b>
$form{$field}<p>\n";
# Если указан
порядок сортировки, отсортировать поля
# формы в указанном
порядке.
elsif ($Config{'sort'}
=~ /border :.*,.*/) {
# Присвоить временной переменной $sort_order порядок сортировки,
# убрать лишние
переносы строк и пробелы, убрать команду order:
# и разложить поля сортировки в массив.
$sort_order = $Conf ig{'sort'} ;
$sort_order =~ s/(\s+|\n)?, (\s+| \n) ?/, /g;
$sort_order =~ s/ (\s+) ?\n+(\s+)?//g;
$sort_order =~
s/order://;
@sorted_f ields
= split (/,/, $sort_order) ;
# Для каждого
поля сортировки, если у него есть значение
# или если установлена
опция печати пустых полей,
# распечатать
поле формы и его значение. foreach $sorted_f ield (@sorted_f ields) {
if ($Config{'print_blank_f
ields'} || $form{$sorted_field) ) { print "<b>$sorted_field:</b>
$form{$sorted_field}<p>\n" ;
# Иначе, использовать
порядок, в котором поля были переданы.
else {
# Для каждого
поля формы, если оно имеет значение или
# установлена
опция печати пустых полей, распечатать поле
# формы и его
значение. foreach $ field (@field_Order) {
if ($Config{'print_blank_f
ields'} | | $form{$f ield} ) { print "<b>$field:</b>' $form{$f
ield}<p>\n";
}
print "<p><hr
size=l width=75%xp>\n";
# Проверить наличие ссылки возврата и распечатать ее, если нашли.
if ($Config{'return_link_url'}
&& $Conf ig{'return_link_title'} ) {
print "<ul>\n";
print "<lixa
href =\"$Conflg{'return_link_url'} \">$Conf ig{'return_
->link_title'}</a>\n";
print "</ul>\n";
# Распечатать
нижнюю часть страницы.
print «"(END
HTmL fOOTER)";
<hr size=l
width=75%xp>
<centerxfont
size=-lxahref="http: //www.worldwidemart.com/scripts,
->formmail.shtml">formmail</a> V1. 6 ©
1995 -1997 matt Wright <br> A free Product of
<a href="http: //www.worldwidemart .com/scripts/">matt ' s
->Script Archive,
inc.</ax/fontx/center>
</body>
</html>
(END HTmL fOOTER)
sub send_mail
{
# Локализация переменных, используемых в этой подпрограмме.
local ($print_conf.ig,
$key, $sort_order, $sorted_field, $env_report) ;
# Открыть почтовую
программу open (mAiL, " | $mailprog -t") ;
- print mAiL "To:
$Config{'recipient'}\n";
print mAiL "from:
$Conf ig{'email'} ($Config{'realname'} ) \n" ;
# Проверить тему
сообщения
if ($Conf ig{ ' subject '}) { print mAiL "Subject:
$Conf ig{'subject'}
\n\n"} else {print mAiL "Subject: WWW form Submission\n\n" }
print mAiL "Ниже находится предоставленная вами информация .
От кого : \n" ; print mAiL "$Conf ig{'realname'} ($Conf ig{'email'} ) , дата:
$date\n";
print mAiL "-" x 75 . "\n\n";
if (@Print_Config)
" {
foreach $print_conf
ig (@Print_Conf ig) { if ($Conf ig{$print_conf ig} ) {
print mAiL "$print_config:
$Config{$print_conf ig} \n\n";
} } }
# Если указано, отсортировать по алфавиту:
if ($Config{'sort'}
eq 'alphabetic') { foreach $field (sort keys %form) {
# Если поле имеет
значение или установлена опция печати пустых
# полей, распечатать поле формы и его значение,
if ($Config{'print_blank_fields'}
| | $form{$field) $form{$field} eq '0') {
print mAiL "$field:
$form{$field}\n\n"; } } }
# Если указан
порядок сортировки, отсортировать поля
# формы в указанном
порядке .
elsif ($Config{'sort'}
= ~ /^order :.*,.*/) {
# Убрать лишние
переносы строк и пробелы, убрать команду order:
# и разложить поля сортировки в массив.
$Config{'sort'} =~ s/(\s+|\n)?, (\s+ | \n) ?/ , /g;
$Config{'sort'} =~ s/ (\s+) ?\n+ (\s+) ?//g;
$Config{'sort'} =- s/order://;
@sorted_fields
= split(/,/, $Config{'sort'} ) ;
# Для каждого
поля сортировки, если у него есть значение или еслк
# установлена
опция печати пустых полей, распечатать поле
# формы и его
значение.
foreach $sorted_field
(Ssorted_fields) {
if ($Config{ 'print_blank_f
ields'} | | $form{$sorted_field} | | $form{$sorted_f ield} eq '0') { print mAiL
"$sorted_field: $form{$sorted_f ield}\n\n";
# Иначе, использовать
порядок, в котором поля были переданы, else {
# Для каждого поля формы, если оно имеет значение или
# установлена опция
печати пустых полей, распечатать
# поле формы и
его значение, foreach $field (@field_Order) {
if ($Config{'print_blank_fields'}
| | $form{$field} | | $form{$field} eq '0') { print mAiL "$field: $form{$field}\n\n";
}
}
}
print mAiL "-"
x 75 . "\n\n";
# Если указаны переменные среды, послать их адресату,
foreach $env_report
(@Env_Report) {
if ($ENV{$env_report})
{
print mAiL "$env_report:
$ENV{$env_report}\n";
} } close (mAiL);
}
sub check_email
{
# Инициализация
локальной переменной email
# параметром вызова подпрограммы.
$email = $_[0];
# Если e-mail адрес содержит:
if ($email =-
/(@.*@)|(\.\.)|(@\.) (\.@)|(^\.)/ ||
# e-mail адрес
имеет неправильный синтакс. Или, если синтакс не
# соответствует следующему шаблону регулярного выражения, то
# проверка основного
синтаксиса обнаруживает ошибку.
$email !~ /^.+\@(\[?)[a-zA-Z0-9\-\.3+\.([a-zA-Z]
->{2,3}|[0-9]{1,3})(\]?)$/) {
# Основной синтаксис
требует: один или более символов перед
# знаком @, за которым следует необязательный символ '[',
# затем любое число
букв, цифр, дефисов и точек
# (допустимые
символы домена/iP), и в конце стоит точка,
# за которой находятся
2 или 3 буквы (для суффиксов домена)
# или от 1 до
3 цифр (для iP-адресов). В конце также может
# стоять символ
'
]
', так
как допустимо иметь email-адрес,
# подобный user@[255.255.255].
# Возвратить код
ошибки, если e-mail
# адрес не удовлетворяет
синтаксису, return 0;
}
else {
# Возвратить true,
e-mail адрес соответствует правилам, return 1 ;
} }
sub body_attributes
{
# Проверить цвет
фона
if .($Config{
'bgcolor'}) { print " bgcolor=\"$Config{'bgcolor'} \"" }
# Проверить фоновый
рисунок
if ($Config{background'})
{ print " > background=\"$Config{background'}\"" }
#Проверить цвет
ссылок
if ($Config{'link_color'})
{ print " link=\"$Conf ig{'link_color'} \" " }
# Проверить цвет
посещенных ссылок
if ($Conf ig{'vlink_color'})
{ print " vlink=\"$Conf ig{'vlink_color'} \"" }
# Проверить цвет
активной ссылки
if ($Config{'alink_color'})
{ print " alink=\"$Conf ig{'alink_color'} \"" }
# Проверить цвет
текста
if ($Config{'text_color'})
{ print " text=\"$Conf ig{'text_color'}A"" }
sub error {
# Локализация
переменных и присвоение параметров подпрограммы.
local($error,@error_fields)
= @_;
local($host,$missing_field,$missing_field_list);
if ($error eq
tad_referer') {
if ($ENV{'HTTP_REfERER'} =~ m| ~https? :
// ( [ \w\ . ]
) | i) { $host = $1; print «"(END ERROR HTmL) ";
Content-type:
text/html
<html> <head>
<title>HeKoppeктным
рекомендатель - в доступе отказано</title> </head>
<body bgcolor=#ffffff
text=#000000> <center>
<table border=0 width=600 bgcolor=#9C9C9C>
<tr><th><font
size=+2>Некорректный рекомендатель — в доступе
_>OTKa3aHo</fontx/th></tr>
</table>
<table border=0 width=600 bgcolor=#CfCfCf> <tr><td>
Фopмa пытается
использовать
<a href="http: //www.worldwidemart.com/scripts/formmail.shtiru">formmail</a>
по адресу
<tt>$ENV{'HTTP_REfERER'}</tt>
, что является
недопустимым для доступа к этому CGi-сценарию.<р>
Если Вы пытаетесь сконфигурировать formmail для запуска этой формы,
->вам нужно добавить следующую информацию к \@referers, более
->подробно об
этом написано в файле READmE.<р>
Добавьте <tt>'$host'</tt> в ваш массив <tt><b>\@referers</b></tt>.
->chr size=1>
<centerxfont size=-l>
<a href="http: //www.worldwidemart.com/scripts/fonnmail.shtnil">
->formmail</a> Vi.6 © 1995 - 1997 matt Wright<br>
A free Product of <a href=" http://www.worldwidemart.com/scripts/ ">
->matt's Script
Archive, inc.</a> </font></center>
</td></tr>
</table>
</center> </body> </html>
(END ERROR HTmL)
} else {
print «"(END
ERROR HTmL)"; Content-type: text/html
<html> '
<head>
<title>formmail
vl.6</title> </head>
<body bgcolor=#ffffff
text=#000000> <center>
<table border=0 width=600 bgcolor=#9C9C9C> <tr>
<th><font
size=+2>formmail</font></th></tr> </table>
<table border=0
width=600 bgcolor=fCfCfCf>
<tr><th><tt><font
size=+l>Copyright 1995 - 1997 matt Wright<br> Version 1.6 - Released
may 02, 1997<br>
A free Product of
<& href="http: //www.worldwidemart.com/scripts/">
->matt's Script
Archive, inc. </a></font>< /tt>< / th>< / tr>
</table> </center> </body> </html> (END ERROR HTmL)
} }
elsif ($error
eg 'request_method') {
print «"(END
ERROR HTmL)"; Content-type: text/html
<html> <head>
<title>Ошибка:
Метод 3anpoca</title> </head>
<body bgcolor=#ffffff
text=#000000> <center>
<table border=0 width=600 bgcolor=#9C9C9C> <tr>
<th><font
size=+2>Error: Request method</font></th></tr> </table>
<table border=0
width=600 bgcolor=#CfCfCf>
<tr><td>meтод запроса предоставленной Вами формы не совпадает ни с
<tt>GET</tt>, ни с <tt>POST</tt>. Пожалуйста, проверьте форму и
->убедитесь,
что оператор
<tt>method=</tt> записан в верхнем регистре и является <tt>GET</tt>
->либо <tt>POST</tt>.<p>
<centerxfont
size=-l>
<а href="http: / /www. woridwidemart. com/scripts/ formmai1. shtml">
->formail</a> vi.6 © 1995 - 1997 matt Wright<br>
A free Product of <a href=" http://www.worldwidemart.com/scripts/ ">matt's
->Script Archive, inc.</a> </font></center> </td></tr>
</table>
</center> </body> </html>
(END ERROR HTmL)
} elsif ($error eg 'no_recipient') {
print «"(END
ERROR HTmL)";
Content-type:
text/html
<html> <head>
<title>Omn6Ka:
Нет </head>
<body bgcolor=#ffffff
text=#000000i> <center>
<table border=0
width=600 bgcolor=#9C9C9C> <tr><thxfont size=+2>Error: No Recipient</fontx/th></tr>
</table>
<table border=0
width=600 bgcolor=iCfCfCf>
<tr><td>b
переданных для formmail данных не указан получатель. Пожалуйста, убедитесь,
что Вы записали в поле формы 'recipient'
e-mail адрес. Более подробную
информацию по заполнению поля формы recipient можно найти в файле READmE.<hr
size=l>
<centerxfont
size=-l>
<a href=" http://www.worldwidemart.com/scripts/formmail.shtml ">
->formmail</a> Vi.6 © 1995 - 1997 matt Wright
<br> A free Product of <a href=" http://www . worldwidemart. com/scripts/">matt's
->Script Archive,
inc.</a>s </ f ontx/eenter> </td></tr> </table>
</center> </body> </html>
(END ERROR HTmL)
}
elsif ($error
eq 'missing_f ields') {
if ($Config{'missing_fields_redirect'})
{
print "Location:
$Conf ig{'missing_£ields_redirect'} \n\n"; } else {
foreach $missing_field
(@error_fields) {
$missing_field_list
.= " <li>$missing_f ield\n";' }
print «"(END
ERROR HTmL)";
Content-type:
text/html
<html> <head>
<title>Ошибка:
Незаполненные пoля</title> </head> <center>
<table border=0
width=600 bgcolor=#9C9C9C>
<tr><th><font
size=+2>0шибка: Незаполненные поля</font></th></tr> </table>
<table border=0 width=600 bgcolor=fCfCfCf> <tr>
<td>Следующие
поля в предоставленной Вами форме незаполнены:<р>
<ul>
$missing_field_list
</ulxbr>
Эти поля должны быть заполнены
для успешной подачи формы. <р> Пожалуйста, используйте кнопку back браузера
для возврата к форме ->и исправьте данные. <hr size=l> <center><font
size=-l>
<a href ="http : //www. worldwidemart . com/scripts/formmail.shtml">
->formmail</a> Vi. 6 © 1995 - 1997 matt Wright<br> A free Product of
<a href="http: //www. worldwidemart. com/scripts/">matt's
->Script Archive, inc.</a> < / font>< / center> </td></tr>
</table>
</center> </body> </html> (END ERROR HTmL)
exit; }
Эта профамма возвращает
пользователю HTmL-страницу, сообщающую о том, что контактна)? информация в форме
обработана или содержит ошибки, если таковые имеются. Это очень важный компонент
всех CGi-программ - они должны либо вернуть правильные данные браузеру (например.
HTmL-документ или содержимое файла с изображением), либо перенаправить браузер
на правильный URL.
Профамма f ormmail реализует
много других функций: она может установить строку темь; (subject) при отправке
e-mail и выполнить проверку того, что сценарий не используется незаконно пользователями
с других Web-сайтов. Более детальная информация доступна на Web-сайте профаммы.
Последний, важный этап
создания Web-сайта - оформление офаничений доступа для каталога /var/www/html/authors/,
чтобы только уполномоченные пользователи имели доступ к файлам в этом каталоге.
Чтобы сформулировать эти офаничения, нужно решить две задачи Во-первых, следует
создать файл пользователей с перечнем необходимых пользователей (мы уже делали
это в предыдущем парафафе, посвященном защите каталогов с использованием управления
доступом). Нужно создать офаничения доступа для всех пользователей, которым
предоставляется доступ к каталогу.
Во-вторых, нужно создать
фуппу. Назовем ее authors, чтобы было проще выполнять работ по администрированию
доступа к каталогу. Создается эта фуппа добавлением в файл групп (group) Web-сервера
строки для фуппы, которая выглядит примерно так:
authors:
author1
author2 author3
Эта строка указывает, что
трем пользователям предоставляется доступ к каталогу.
Наконец, нужно создать
файл .htaccess в каталоге /var/www/html/authors/ ("Auth" в приведенных
ниже командах относится к аутентификации, authentication, а не к нашей группе
authors).
AuthName Just
for Authors AuthType basic
AuthUserfile /etc/httpd/conf
/users AuthGroupfile /etc/httpd/conf
/groups require
group authors
AuthName указывает отображаемую
пользователю подсказку. AuthUserfile сообщает серверу, где искать список допустимых
пользователей и паролей, a AuthGroupfile - где находится список допустимых групп.
Наконец, команда require указывает, что только членам группы authors нужно предоставить
доступ к каталогу.
Если пользователь попытается
получить доступ к данному каталогу в начале сессии, он увидит диалоговое окно
аутентификации, отображаемое браузером, подобное тому, которое отображает Netscape-(pnc.
32.5).
Рис. 32.5.
Диалоговое окно аутентификации пользователя в Netscape
По умолчанию, если пользователь
не пройдет аутентификацию, он получит страницу с сообщением об ошибке и предложением
пройти аутентификацию. Для предоставления специализированной страницы, извещающей
об ошибке аутентификации, следует отредактировать файл httpd.conf, чтобы указать
на специализированное сообщение об ошибке, добавив в файл следующую строку:
ErrorDocument
401 /error.html
Этот элемент указывает, что при возникновении ошибки 401 (Authorization Required - Требуется аутентификация) сервер должен возвращать указанный URL вместо сообщения по умолчанию. Когда пользователь не пройдет аутентификацию, он получит модифицированную страницу с сообщением о неудачной аутентификации.