Построение Web-сайта

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

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

В рамках поставленной задачи попытаемся создать сайт, содержащий HTML-документы и изображения, использующий CGI-программирование и выполняющий контроль доступа защищенного паролем раздела на сайте.

Создадим файлы, необходимые для реализации этой структуры. Подразумевая использование конфигурации, рассмотренной ранее в главе, поместим корневой каталог для дерева 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>

Остальные страницы будут выглядеть примерно так же, кроме формы для контактов /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>

Эта страница содержит форму и ссылку на 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 &copy;

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 &copy; 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 &copy; 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 &copy; 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 &copy; 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).

По умолчанию, если пользователь не пройдет аутентификацию, он получит страницу с сообщением об ошибке и предложением пройти аутентификацию. Для предоставления специализированной страницы, извещающей об ошибке аутентификации, следует отредактировать файл httpd.conf, чтобы указать на специализированное сообщение об ошибке, добавив в файл следующую строку:

ErrorDocument 401 /error.html

Этот элемент указывает, что при возникновении ошибки 401 (Authorization Required - Требуется аутентификация) сервер должен возвращать указанный URL вместо сообщения по умолчанию. Когда пользователь не пройдет аутентификацию, он получит модифицированную страницу с сообщением о неудачной аутентификации.