ЛАБОРАТОРНАЯ РАБОТА №7

Тема: Разработка CGI скриптов на языке Python

Цель: Рассмотрение особенностей разработки серверных приложений

ОГЛАВЛЕНИЕ

1 Особенности интерфейса CGI
1.1 Формат передаваемых данных
1.2 Конфигурирование Web-сервера
1.3 Коды статуса запроса
2 Разработка клиентской части приложения
3 Особенности разработки CGI скриптов, реализующих серверную часть приложения
3.1 Использование модуля cgitb
3.2 Методы модуля cgi
3.3 Разработка CGI скрипта с использованием метода parse() модуля cgi
Пример №1
Индивидуальные задания

 Оглавление

1 Особенности интерфейса CGI

Одним из средств, которые позволяют осуществить взаимодействие между клиенской и серверной частями приложения, является интерфейс CGI (Common Gateway Interface – общий шлюзовый интерфейс), имеющий реализации как для Windows-ориентированных программ, так и для приложений, функционирующих в среде Unix. Этот интерфейс разработан так, чтобы для создания серверного приложения можно было использовать любой язык программирования, который может работать со стандартными устройствами ввода/вывода. Серверная часть приложения, которая обрабатывает данные клиента, полученные с использованием CGI-интерфейса, называется CGI-приложением.
При использовании CGI-приложений информация на Web-странице клиента, предназначенная для передачи на сервер, предствляется в виде HTML-форм.
Итерфейс CGI вместе с HTML-формой были разработаны в 1991 Марком Андерссеном и Эриком Бином в национальном центре суперкомпьютерных приложений NCSA (Center for Supercomputing Applications) при университете штата Иллинойс (США) в ходе работы над браузером NCSA Mosaic, первым браузером под операционную систему Microsoft Windows. На основе его исходного кода были разработаны браузеры Netscape Navigator и Micosoft Internet Explorer.

 Оглавление

1.1 Формат передаваемых данных

При передаче данных формы на сервер с использованием CGI-интерфейса с помощью атрибутов method и enctype тега <form> могут быть указаны метод передачи и MIME-тип данных.
MIME (Multipurpose Internet Mail Extensions – многоцелевые расширения почты Internet, произносится как <майм>) – первоначально стандарт, описывающий передачу различных типов данных по электронной почте. Сейчас – спецификация для кодирования информации и форматирования сообщений таким образом, чтобы их можно было пересылать по сети Internet.
Формат MIME поддерживает передачу нескольких блоков данных в пределах одного сообщения. Причем блоки могут передаваться не только в виде одноуровневой последовательности, но в виде иерархии с вложением элементов друг в друга.
Для обозначения множественного содержимого используются типы multipart/*. Работа с такими типами осуществляется по правилам, описанным в RFC 2046.
Для передачи множественного сообщения в заголовок Content-Type добавляется атрибут boundary (граница), который обозначает последовательность символов, разделяющих части сообщения. Граница может состоять из цифр, букв и символов <'()+_,-./:=?>. При использовании специальных символов (не цифр и букв) значение параметра boundary следует заключать в двойные кавычки. Максимальная длина границы – 70 символов.
Для формы допускается использовать следующие два MIME-типа данных:

Первый тип данных (url-кодированные) задается по умолчанию и используется при передаче любых данных формы (за исключением файлов). Второй тип может быть указан только для метода POST, задает структуру данных, имеющую несколько частей, и используется при передаче файлов из формы на сервер.
Если MIME-тип не указан (что является типичным) или указан тип application/x-www-form-urlencoded, то имена полей формы и их значения передаются на сервер в таком формате:

имя=значение&имя=значение&имя=значение& . . .

При этом используется url-кодирование передаваемых имен и значений, которое заключается в следующем:

 Оглавление

1.2 Конфигурирование Web-сервера

При разработке приложения в рамках технологии "клиент-сервер" необходимо выбрать Web-сервер и осуществить его конфигурирование. В примерах, приведенных в описании данной лабораторной работы, предполагается использование сервера Apache. Он является кросс-платформенным и нашел широкое применение у разработчиков клиент-серверных приложений. Однако для выполнения данной работы можно выбрать любой из доступных Web-серверов.
Конфигурирование сервера Apache осуществляется путем задания необходимых значений директивам, содержавшимся в его файле конфигурации httpd.conf. Поскольку этот файл содержит довольно много директив, приведем лишь некоторые из них, имеющих прямое отношение к выполняемой работе (в скобках указано заданное значение директивы):

Остальные директивы файла конфигурации httpd.conf необходимо просмотреть (все они имеют комментарии) и при необходимости изменить их начальные значения.
При всяком изменении значений конфигурационного файла необходимо осуществлять перезапуск Web-сервера.
Если серверное приложение задается не в виде exe-файла, а является программой, написанной на языке Python и заданной в виде файла с расширением .py, то необходимо дополнительно выполнить следующие изменения в конфигурационном файле Apache:

 Оглавление

1.3 Коды статуса запроса

Коды статуса (Status) используются в http-протоколе для передачи сервером браузеру статуса запроса. Поле статуса заголовка содержит три цифры, за которыми следует строка текста, поясняющая код. Коды статуса сгруппированы по первой цифре:

Полный список кодов статуса можно найти по адресу:
http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html.

 Оглавление

2 Разработка клиентской части приложения

Клиентская часть приложения содержит HTML-документ, реализованный в виде примера №1, содержащего форму (тег <form>), с помощью которого осуществляется прием данных от клиента и передача с использованием интерфейса CGI (см. раздел 1) запроса для обработки серверной программе cgi_parse_form.py.
HTML-форма примера №1 имеет поля, предоставляющие пользователю такие возможности:

Свойства элементов формы (цвет и размер символов, выравнивание текста, цвет фона и др.) заданы с помощью файла lab.css, который подключается к HTML-документу примера №1 и содержит следующие CSS:

body {
margin:1.5cm 1.5cm 2.0cm 2.5cm;
font-size:5.5mm;
color:#000080;
background-color:#eeeeee;
}
h1 {
text-align:center;
color:#d0d;
text-transform:uppercase;
font:italic 0.25in tahoma;
}
input, textarea, option, button {
background:#eeffee;
color:#005000;
font-size:6mm;
border:outset 2px black;
}
td {
vertical-align:middle;
}

 Оглавление

Пример №1

<!DOCTYPE html>
<html>
<head>
<title>Обработка данных формы</title>
<link rel="stylesheet" href="lab.css">
</head>
<body>
<h1>Обработка данных формы</h1>
<form method="get" action="http://zykov/PYTHON/cgi_parse_form.py">
<table align="center" width="50%" style="color:#000080;font-size:6mm">
<tr> <td> Введите имя
<td><input type="text" size="10" class="form" name="name"
<tr><td cols="2">
<span style="margin-left:2cm; outline:1px solid blue;font-size:5.5mm"> Отметьте то, что хотите получить
</span>
<tr><td>Данные HTML-формы
<td><input type="checkbox" name="check1" value="data">
<tr><td>Переменные окружения <td><input type="checkbox" name="check2">
<tr><td>Рисунки<td><input type=checkbox name="check3" value="img">
<tr> <td>Примеры формирования
<td><select name="help" size="3" multiple class="form">
<option value="str"> строки
<option value="list"> списка
<option value="tuple"> кортежа
<option value="set"> множества
<option value="dict"> словаря
</select>
<tr> <td> <input type="reset" value="Сброс" class="kn">&nbsp;&nbsp;
<input type="submit" value="Передача" class="kn">
</table><br>
</form>
</body>
</html>

 Оглавление

3 Особенности разработки CGI скриптов, реализующих серверную часть приложения

CGI скриптом будем называть программу (скрипт), которая выполняется на стороне сервера и использует интерфейс CGI (см. раздел 1) для взаимодействия с клиетнтской частью.
Программа на языке Python, выполняемая на Web-сервере, имеет два основных отличия от программ, выполняемым на стороне клиента:

Первая строка программы начинается с двух символов #!, которые иногда (в том числе в документации языка Python) называются shebang, после которых указывается путь к интерпретатору языка Python (#!c:/ . . . /Python/Python35-32/python.exe), что позволяет серверу вызвать интерпретатор для обработки скрипта. Отметим, что слово shebang, по одной из версий, образовано названиями этих двух начальных символов – sh[arp]+bang (bang – одно из названий восклицательного знака).
Затем указывается заголовок http протокола, который отделяется от его тела пустой строкой, реализованной функцией print(). В http-заголовке задан параметр, который указывает, как данные, переданные сервером, будут интерпретироваться браузером на стороне клиента. В данном случае будет сформирована Web-страница. Если для параметра Content-Type будет задано значение text/plain, то браузер воспримет данные, переданные сервером, как простой текст и в случае передачи HTML-документа выведет на экран его содержимое (подобно режиму "Просмотр HTML-кода").
Необходимо отметить, что http-заголовок с параметром Content-Type применим в серверных приложениях, использующих интерфейс CGI. В сдучае использования для обмена данными с клиентом технологии AJAX (см. раздел 1 лаб. раб. №10) этот http -заголовок применять не следует.
Имеется несколько способов получения доступа к данным HTML-формы, переданным на сервер. В данной лабораторной работе выбран способ, основанный на использовании метода parse() модуля cgi (см. подраздел 3.3). Для реализации этого способа к серверной программе необходимо подключить следующие модули языка Python:

import cgitb, cgi

 Оглавление

3.1 Использование модуля cgitb

Модуль cgitb (cgi traceback – cgi отладчик) предназначен для формирования в случае возникновения исключения при работе CGI скрипта отладочной информации, содержащей фрагмент кода программы, в котором отмечена строка с ошибкой, описание исключения и некоторые другие данные, например, путь к выполняемой программе.
Формат и способы предоставления этих данных пользователю или администратору задаются c помощью метода enable([display[,logdir[,context[,format]]]]) при инициализации модуля. Все параметры метода являются необязательными и задают следующее:

Модуль cgitb нашел применение в серверной программе cgi_parse_form.py во время ее отладки. При его инициализации:

cgitb.enable(logdir= "D:/ . . . Apache Group/Apache/root/Python/TMP/", context=7)

были указаны: путь к каталогу, содержащему отладочную информацию (logdir), и размер фрагмента программы (число строк), содержащего ошибку (context). Значения остальных параметров заданы по умолчанию.

 Оглавление

3.2 Методы модуля cgi

Модуль cgi имеет следующие методы, которые могут быть искользованы при разработке CGI скриптов:

 Оглавление

3.3 Разработка CGI скрипта с использованием метода parse() модуля cgi

Для получения доступа к данным, переданным браузером из HTML-формы клиента серверу, можно воспользоваться методом parse() модуля cgi, все параметры которого имеют значения, заданные по умолчанию. Для параметра keep_blank_values такое значение равно 0, что означает, что незаполненные поля HTML-формы сервером не будут обрабатываться (см. подраздел 3.2).
Поскольку предполагается, что пользователь в поле ввода имени свое имя может не указывать, то для обработки этого поля в любом варианте (заполненном и незаполненном), необходимо при вызове метода parse() явно задать значение параметра keep_blank_values (остальные параметры имеют значения, заданные по умолчанию):

form=cgi.parse(keep_blank_values=1)

Этот метод возвращает данные HTML-формы, полученные сервером, в виде словаря form, ключами которого являются имена полей формы (заданные атрибутами name), а значения полей формы представлены в виде списков. Причем поля HTML-формы, заданные тегом <input>, которые имеют одиночные значения, являются одноэлемнтными списками, поля, которые могут иметь множественное значение (например, тег <select> с атрибутом multiple), являются списками с несколькими элементами.
Поэтому доступ к значениям полей HTML-формы можно получить следующим образом:

Серверная программа после приема и обработки данных формирует ответ в виде HTML-документа, который отсылается клиенту и воспроизводится браузером на стороне клиента в виде Web-страницы. Для упрощения форматирования текста были разработаны следующие форматы представления данных в виде констант языка Python:

Поскольку эти константы могут быть использованы разными программами при форматировании данных, отсылаемых клиенту, они помещены в модуль my_mod, который реализован в виде файла my_mod.py.
В качестве примера использования метода parse() модуля cgi для доступа к данным HTML-формы рассмотрим приложение, клиенткая часть которого реализована в виде примера №1, а серверная – в виде CGI скрипта cgi_parse_form.py:

#!c:/ . . . /Python/Python35-32/python.exe
print ( "Content-Type: text/html" )
print ()

import cgi, cgitb
from os import environ as env
from my_mod import *
HELP={ 'str' : 'строки: s=\'Python\'' ,
'list' : 'списка: a_list=[255,"web",1.33,True]' ,
'tuple' : 'кортежа: a_tuple=(\'name\',100)' ,
'set' : 'множества: a_set={1,2,\'a\',\'b\'}' ,
'dict' : 'словаря: a_dict={\'name\':\'Bob\',\'sport\':\'football\'}' }
cgitb.enable(logdir= "D:/ . . . Apache Group/Apache/root/Python/TMP/", context=7)
form=cgi.parse(keep_blank_values=1)
name= 'клиент'
if form[ 'name' ][0]: name=form[ 'name' ][0]
print (H2, "Ув. " ,name, "!" , sep= "" )
if "check1" in form or "check2" in form or "check3" in form or "help" in form:
print ( 'Вам предоставляются:' )
if 'check1' in form:
print (H, "Данные HTML-формы:" )
print (D, form)
if 'check2' in form:
print (H, "Переменные окружения:" )
print (D, 'REQUEST_METHOD= ' , env[ 'REQUEST_METHOD' ])
print (D, 'QUERY_STRING= ' , env[ 'QUERY_STRING' ])
print (D, 'HTTP_USER_AGENT= ' , env[ 'HTTP_USER_AGENT' ])
if 'check3' in form:
print (H, "Рисунки:" )
print (H, "<img src='everest.jpg'>" )
print (H, "<img src='flower.jpg'>" )
if 'help' in form:
print (H, "Примеры создания:" )
for el in form[ 'help' ]:
print (D, HELP[el])
else : print ( 'Вы действительно ничего не хотите заказать?' ),

которая выполняет следующие действия:

 Оглавление

Результаты работы программы cgi_parse_form.py, полученные при использовании браузеров Internet Explorer, Chrome, Firefox, Opera и Safari, показывают, что она правильно обрабатывает различные поля HTML-формы как с использованием латинских букв, так и при использовании кириллицы. Поэтому способ доступа к данным, переданным клиентом серверу, основанный на использовании метода cgi.parse(), является основным и будет в дальнейшем исиользоваться как при обработке данных HTML-формы (см. пример №1), так и при передаче данных клиента с использованием технологии AJAX (см. пример №1 лаб. раб. №10).

 Оглавление

Индивидуальные задания

Разработать приложение на базе технологии "клиент-сервер". При этом клиентская часть передает на сервер имя пользоватекля и номера функций, а серверная часть, написанная на языке Python, выполняет эти функции и возвращает пользователю результат.
В задачи клиентской части входит: разработать HTML-документ, содержащий форму, обязательными элементами которой являются:

Функции по группам делятся следующим образом:

В задачи серверной части входит:

Таблица 1 – Перечень индивидуальных заданий

Номер
п/п
ТегиСлучайные числаФункции
ДиапазонКоличествоГруппа 1Группа 2Группа 3
1input(-5, 5)10а)а)а)
2select(-7, 21)20б)б)б)
3input(-20, 5)7в)в)а)
4select(-25, 40)22г)а)б)
5input(-7, 12)8д)б)а)
6select(-22, 15)21а)в)б)
7input(-12, 31)40б)а)а)
8select(-14, 8)8в)б)б)
9input(-13, 20)50г)в)а)
10select(-4, 3)12д)а)б)
11input(-33, 44)16а)б)а)
12select(-55, 66)33б)в)б)
13input(-7, 5)14в)а)а)
14select(-19, 28)50г)б)б)
15input(-8, 5)7д)в)а)
16select(-24, 26)36а)а)б)
17input(-11, 9)19б)б)а)
18select(-9, 3)13в)в)б)
19input(-17, 42)39г)а)а)
20select(-3, 3)11д)б)б)

 Оглавление