Построение 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 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 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 width=600 bgcolor=#9C9C9C>
<tr><th><font size=+2>Некорректный рекомендатель — в доступе
_>OTKa3aHo</fontx/th></tr> </table>
<table 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 width=600 bgcolor=#9C9C9C> <tr>
<th><font size=+2>FormMail</font></th></tr> </table>
<table 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 width=600 bgcolor=#9C9C9C> <tr>
<th><font size=+2>Error: Request Method</font></th></tr> </table>
<table 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 width=600 bgcolor=#9C9C9C> <tr><thxfont size=+2>Error: No Recipient</fontx/th></tr> </table>
<table 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 width=600 bgcolor=#9C9C9C>
<tr><th><font size=+2>0шибка: Незаполненные поля</font></th></tr> </table>
<table 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 вместо сообщения по умолчанию. Когда пользователь не пройдет аутентификацию, он получит модифицированную страницу с сообщением о неудачной аутентификации.