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

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

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

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

Определим структуру сайта, как показано на рис. 32.2.

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

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