Сервер Web своими руками. Язык HTML, приложения CGI и ISAPI
Как это устроено
В 23 томе “Библиотеки системного программиста”, который называется “Глобальные сети компьютеров. Практическое введение в Internet, E-Mail, FTP, WWW и HTML, программирование для Windows Sockets” мы описали основы технологий, которые широко используются в сети Internet. Если вы никогда раньше не работали в этой сети и не имеете о ней ни малейшего представления, указанный том может послужить для вас отправной точкой. В книге, которую вы сейчас читаете, есть все необходимое для создания сервера Web или размещения своей информации на сервере Web поставщика услуг Internet, поэтому предварительное знакомство с 23 томом “Библиотеки системного программиста” не обязательно, хотя и желательно.Если же вы знакомы с технологиями Internet, то можете пропустить первую главу и сразу перейти ко второй, где мы рассказываем о создании статических документов HTML.
Создание документов HTML
В этой главе мы займемся изготовлением простейших статических документов на языке HTML. Научившись создавать такие документы, вы сможете разместить их на сервере WWW поставщика услуг Internet или даже создать свой виртуальный сервер WWW на сервере этого поставщика.Язык HTML в своем развитии прошел несколько версий. Заметим, что после версий 1.0 и 2.0 в марте 1995 года был подготовлен черновой вариант версии 3.0, в которой по сравнению с версией 2.0 было много добавлений. Не углубляясь пока в детали, отметим, что основные производители навигаторов (фирмы Netscape и Microsoft) разработали свои расширения языка HTML, которые оказались несовместимыми между собой. В настоящее время ситуация осталась прежней, хотя совместимость навигаторов Netscape Navigator версии 3.0 и Microsoft Internet Explorer версии 3.0 несколько улучшилась.
На смену неудачному, так и не реализованному стандарту языка HTML версии 3.0, был разработан стандарт версии 3.2. В разработке этого стандарта участвовали такие фирмы как Netscape Communications Corporation, Microsoft, IBM, Novell, SoftQuad, Sun Microsystems и Spyglass. Возможно, что такой представительный состав разработчиков стандарта положительно повлияет на совместимость навигаторов.
Таблицы в документах HTML
Очень часто приходится размещать в документе HTML табличные данные. Это можно сделать двумя способами.Первый способ заключается в том, что вы оформляете текст таблицы шрифтом с фиксированной шириной символов, а для выравнивания колонок используете символы пробела. Этот способ будет работать, однако он едва ли позволит вам создать таблицу, которая будет выглядеть красиво.
Второй способ предполагает использование операторов языка HTML, специально предназначенных для создания таблиц. Эти операторы открывают перед вами широкие возможности: вы можете использовать рамки вокруг всех или только некоторых ячеек и строк таблицы, создавать таблицы, имеющие заголовки и подписи, размещать в ячейках таблицы не только текст, но и графику или произвольные объекты, использовать в качестве фона для ячеек растровые графические изображения.
Заметим, что таблицы можно использовать в документах HTML не только для отображения табличных данных, но и для решения других задач, например, для размещения различных объектов. Например, в ячейках таблицы могут располагаться графические изображения, ссылки и так далее.
Для ячейки таблицы можно указать цветовой фон и отступ, что позволяет изображать текст на цветном фоне с отбивкой. Этот прием часто используется в Internet, так как значительно улучшает внешний вид страницы.
Графика, анимация, видео и звук
В этой главе мы расскажем о том, как оживить страницы вашего сервера WWW, разместив на них графические изображения, видеофрагменты, анимацию, а также звук, - словом мультимедийную информацию.Для подготовки мультимедийной информации вам могут потребоваться специальные приложения, такие как графические редакторы, средства ввода и обработки звука. В качестве примера мы можем назвать такие графические редакторы как Corel Draw и Adobe Photoshop.
Не исключено, что вам придется приобрести видеокамеру, адаптер для ввода видеосигнала от видеомагнитофона или видеокамеры, а также редактор файлов с видеофрагментами. В 15 томе “Библиотеки системного программиста”, который называется “Мультимедиа для Windows”, мы рассмотрели основные средства и методики, пользуясь которыми вы сможете самостоятельно создавать небольшие видеофрагменты в формате файлов AVI.
Если вы не обладаете художественными талантами, необходимыми для создания графических изображений или видеофрагментов, можно их заказать у художника либо приобрести отдельно. В любом случае вам нужно позаботиться о соблюдении авторских прав на всю информацию, которую вы собираетесь опубликовать на вашем сервере WWW, а также на все приложения, которые вы установите как расширение сервера (программы CGI или расширения типа ISAPI).
Ссылки в документах HTML
До сих пор мы создавали только отдельные документы, демонстрирующие некоторые возможности языка HTML. Ваш сервер WWW будет, возможно, состоять из многих документов HTML, ссылающихся друг на друга и на другие ресурсы Internet.В этой главе мы расскажем о том, как создавать различные ссылки, в том числе с использованием сегментированной графики.
Фреймы
Большинство документов HTML не помещается на одной странице, поэтому для их просмотра пользователю приходится сдвигать документ в окне навигатора. Кроме того, для навигации необходимо искать ссылки на другие документы, которые могут быть расположены в любом, самом неожиданном месте страницы.Вы сможете сделать свой сервер намного удобнее для просмотра, если предоставите пользователю многооконный интерфейс, реализованный при помощи фреймов. В этом случае окно навигатора разделяется на несколько окон (фреймов), в каждом из которых отображается содержимое различных документов HTML (рис. 6.1). Таким образом, можно работать одновременно с несколькими документами.
Рис. 6.1. Страница нашего сервера WWW, реализованная с использованием фреймов
Наша страница состоит из трех фреймов. Первый фрейм расположен в верхней части окна и служит для отображение логотипа. Второй фрейм предназначен для отображения ссылок на различные разделы сервера, представляющие собой ни что иное, как обычные документы HTML. И, наконец, третий фрейм имеет самые большие размеры и предназначен для просмотра документов.
Мы настроили параметры фрейма оглавления и фрейма просмотра таким образом, что пользователь может менять их горизонтальный размер, передвигая мышью вертикальную разделительную линию, расположенную между фреймами. Если содержимое документа не помещается внутри фрейма, в правой части соответствующего окна появляется полоса просмотра.
Пользуясь ссылками в окне фрейма оглавления, вы можете загружать в фрейм просмотра различные документы, которые, в свою очередь, также могут иметь ссылки. Разумеется, мы не претендуем на то, что расположение и назначение фреймов выбраны на нашем сервере оптимальным образом, однако вы можете создать для своего сервера любое количество фреймов и расположить их как угодно.
Заметим, что далеко не все навигаторы способны работать с фреймами. Поэтому несмотря на то что фреймы придают страницам сервера более привлекательный вид и облегчают работу пользователя, их можно встретить далеко не на всех серверах WWW. В качестве альтернативы фреймам обычно применяют таблицы.
Приложения CGI
До настоящего момента мы рассказывали вам о том, как разместить в документах HTML различную статическую информацию. Статическую в том смысле, что она не изменяется во времени без вмешательства администратора сервера WWW. Если сервер WWW содержит только статические документы HTML, то такой сервер мы будем называть статическим, или пассивным.Вне всякого сомнения, пассивные серверы очень нужны, так как далеко не всякая информация изменяется динамически. Однако есть приложения, в которых нужны серверы, не просто отображающие мультимедийную информацию, но и способные вести диалог с пользователем в интерактивном режиме, выполнять обращения к базам данных, а также выполнять другую аналогичную работу. Например, если даже информация по своему характеру является статической, но ее объем чрезвычайно большой, поиск по гипертекстовым ссылкам может отнять слишком много времени. Было бы удобнее в этом случае организовать запросный режим для поиска по ключевым словам.
Серверы, которые ведут диалог с удаленным пользователем или выполняют обработку данных пользователя, мы будем называть активными.
Наиболее известный способ создания активных серверов WWW заключается в использовании так называемых приложений CGI. В отечественной литературе, посвященной серверам WWW, часто встречается транслитерация “CGI-скрипты”, которая произошла от оригинального термина CGI Scripts.
Что кроется за аббревиатурой CGI?
CGI - это стандартный шлюзовой интерфейс (Common Gateway Interface) для запуска внешних программ под управлением сервера WWW. Соответственно, приложениями CGI называются программы, которые, пользуясь этим интерфейсом, получают через протокол HTTP информацию от удаленного пользователя, обрабатывают ее, и возвращают результат обработки обратно в виде ссылки на уже существующий документ HTML или другой объект (например, графическое изображение) или в виде документа HTML, созданного динамически.
Передача информации от удаленного пользователя приложению CGI обычно выполняется следующим образом.
В документе HTML, который создается для ввода информации, предназначенной для обработки, размещается форма ввода. Эта форма состоит из необходимых органов управления: полей редактирования текстовой информации, переключателей, списков и так далее. Больше всего форма ввода похожа на привычные вам диалоговые панели операционной системы Microsoft Windows. Каждому органу управления присваивается произвольное имя. Кроме того, в этой форме должна быть кнопка, которую следует нажать после заполнения формы.
Когда пользователь заполняет форму и нажимает указанную кнопку, данные передаются приложению CGI, путь к которому задается в заголовке формы. Это приложение получает через протокол HTTP данные из полей формы в виде пар значений “имя поля/значение”.
После обработки полученных данных приложение CGI создает документ HTML, и записывает его в стандартное устройство вывода stdout. Этот документ автоматически передается удаленному пользователю.
Все описанные процедуры мы рассмотрим в этой главе более подробно. Кроме того, мы приведем исходные тексты различных приложений CGI. Заметим, что возможны и другие сценарии работы с программами CGI.
Так как приложение CGI является ни чем иным, как программой, вы должны оттранслировать ее для той операционной системы, под управлением которой работает ваш сервер WWW. В некоторых случаях вы можете найти более удобным создавать программы CGI с использованием специально предназначенных для этого интерпретаторов, таких как Perl, или языка пакетных заданий. Например, вы можете создать программу CGI для сервера Microsoft Information Server как обычный пакетный файл *.bat. В нашей книге мы сконцентрируемся на использовании для создания программ CGI мобильного языка программирования C. Транслятор этого языка вы можете найти в любой операционной системе.
Приложения ISAPI
В этой главе мы расскажем о приложениях ISAPI, дополняющих возможности сервера Microsoft Information Server. Все эти приложения можно разделить на две группы: расширения ISAPI и фильтры ISAPI.Расширения ISAPI по своему назначению напоминают уже изученные вами программы CGI. Однако в отличие от последних эти расширения выполнены в виде библиотек динамической компоновки DLL, что имеет ряд преимуществ. Так же как и программы CGI, расширения ISAPI получают данные от навигатора (например, из заполненной удаленным пользователем формы), обрабатывают их и посылают навигатору ответ. Однако вместо чтения содержимого переменных среды и стандартного потока ввода STDIN расширение ISAPI получает данные при помощи специально предназначенных для этого функций. Аналогично, вместо записи выходных данных в стандартный поток вывода расширение ISAPI вызывает специальную функцию.
Фильтры ISAPI также реализуются в виде библиотек динамической компоновки DLL, однако их назначение другое. Фильтры ISAPI способны контролировать весь поток данных, проходящий через сервер, на уровне протокола HTTP. Поэтому их можно применять для решения таких задач, как шифрование или перекодирование данных, компрессия информации, создания собственных процедур подключения пользователей к системе и аутентификации (проверки идентификации пользователей), а также для сбора статистической информации использования ресурсов сервера удаленными пользователями.
Установка и настройка сервера WWW
Для тех, кто решил создать свой собственный сервер WWW или FTP в сети Internet или корпоративной сети Intranet, в этой главе мы расскажем об установке и настройке серверов WWW, созданных Microsoft:Научившись устанавливать эти серверы, вы самостоятельно справитесь с установкой сервера Microsoft Information Server для операционной системы Microsoft Windows NT Server версий 3.51 и 4.0;
Все перечисленные выше серверы бесплатны для легальных владельцев соответствующих версий операционной системы Windows.
Какой сервер из перечисленных выше следует выбрать?
Если вы создаете крупный сервер WWW в сети Internet или Intranet, с которым будут работать десятки пользователей, вам подойдет платформа Microsoft Windows NT. Владельцы версии 3.51 этой операционной системы могут загрузить сервер Microsoft Information Server из сервера WWW корпорации Microsoft. Если же у вас имеется операционная система Microsoft Windows NT Server версии 4.0, то в ее составе уже есть сервер Microsoft Information Server.
Для небольших серверов, с которыми будут работать одновременно всего несколько пользователей, больше подойдет сервер на базе операционной системы Microsoft Windows NT Workstation версии 4.0 и сервера Microsoft Peer WebServices. Заметим, что лицензионное соглашение не позволяет подключаться большому числу пользователей к серверу на базе Microsoft Windows NT Workstation.
Если ресурсы компьютера, на котором должен работать сервер WWW недостаточны для операционной системы Windows NT, вы можете создать сервер WWW на базе Windows 95 и сервера Personal Web Server.
Заметим, что серверы Microsoft Peer WebServices и Microsoft Personal Web Server очень удобно использовать для отладки расширений, таких как приложения ISAPI или программы CGI.
Администрирование сервера Microsoft Peer Web Services
Как мы уже говорили, для администрирования сервера Microsoft Peer Web Services вы можете использовать либо технологию, основанную на HTML, либо запустить приложение Microsoft Internet Service Manager (рис.9.24).
Рис. 9.24. Главное окно приложения Microsoft Internet Service Manager
Сразу после установки сервера Microsoft Peer Web Services в окне приложения Microsoft Internet Service Manager вы увидите состояние сервисов, запущенных на компьютере. По умолчанию автоматически запускается сервис WWW, а сервисы FTP и Gopher находятся в остановленном состоянии.
Для запуска или остановки нужного вам сервиса достаточно выделить этот сервис в столбце Computer и затем нажать одну из трех кнопок управления, расположенных на инструментальной линейке:
| Кнопка | Операция над сервисом | ||
![]() | Запуск после остановки или временной остановки | ||
![]() | Остановка | ||
![]() | Временная остановка |
Вместо кнопок вы также можете воспользоваться строками Start Service, Stop Service или Pause Service, выбрав их из меню Properties.
Остановка сервиса WWW может вам потребоваться, например, при замене программных файлов расширения сервера ISAPI.
Заметим, что если в вашей сети имеется несколько серверов, таких как Microsoft Peer Web Services или Microsoft Internet Information Server, вы сможете управлять ими со своей рабочей станции дистанционно с помощью приложения Microsoft Internet Service Manager. Для добавления сервера в список, отображаемый в главном окне этого приложения вы можете выбрать строку Connect to Server из меню Properties или строку Find All Servers. В первом случае вам придется указать имя подключаемого сервера вручную.
Для настройки параметров сервиса вы должны сделать двойной щелчок левой клавишей мыши по имени компьютера напротив нужного сервиса. При этом на экране появится блокнот настроек. Для сервиса WWW внешний вид этого блокнота представлен на рис. 9.25.

Рис. 9.25. Страница Service блокнота настроек параметров сервиса WWW
В поле TCP Port по умолчанию указан стандартный номер порта для работы с протоколом HTTP. При необходимости вы можете использовать другой номер порта, однако при этом следует сделать соответствующие изменения в настройках навигатора. Изменение номера порта имеет смысл делать только для корпоративных сетей.
Обратите внимание на поля группы Anonymous Logon. По умолчанию программа установки сервера Microsoft Peer Web Services создает в базе данных пользователей идентификатор пользователя вида IUSR_xxxx, где xxxx - имя компьютера. Для пользователя с этим идентификатором программа установки автоматически генерирует пароль. Все удаленные пользователи, которые работают с вашим сервером WWW, подключаются к вашей системе с этим идентификатором и обладают правами доступа, установленными для пользователя с идентификатором IUSR_xxxx.
При необходимости вы можете изменить права доступа к каталогам для пользователя IUSR_xxxx, пользуясь для этого стандартными средствами операционной системы Microsoft Windows NT. Можно даже изменить имя пользователя IUSR_xxxx или пароль. Это нужно сделать в двух местах - в базе данных пользователей Microsoft Windows NT и в диалоговой панели, показанной на рис. 9.25.
С помощью страницы Directories блокнота настроек параметров сервиса WWW, показанной на рис. 9.26, вы можете изменить список каталогов, в которых хранятся объекты сервера, доступные пользователям.

Рис. 9.26. Страница Directories блокнота настроек параметров сервиса WWW
Здесь же вы можете задать имя файла документа HTML, который будет отображаться по умолчанию, если адрес URL содержит только путь к каталогу.
С помощью кнопки Add можно добавить в список новый каталог, а с помощью кнопки Remove - удалить каталог из списка.
Кнопка Edit Properties позволяет изменить параметры каталога. Если нажать на эту кнопку, на экране появится диалоговая панель Directory Properties (рис. 9.27).

Рис. 9.27. Диалоговая панель Directory Properties
Многое в этой диалоговой панели вам уже знакомо по серверу Microsoft Personal Web Service для Windows 95. В частности, в поле Virtual Directory вы можете задать для выбранного каталога имя соответствующего ему виртуального каталога. Например, на рис. 9.27 физическому каталогу e:\drweb\dll соответствует виртуальный каталог с именем /drweb.
В группе органов управления Account Information вы можете указать имя пользователя и пароль для доступа к данному каталогу.
Включив переключатель Virtual Server вы можете разместить на своем сервере еще один, виртуальный, сервер WWW. Для этого к сетевому адаптеру необходимо привязать еще один адрес IP, указав его в поле Virtual Server IP Address. Виртуальные серверы позволяют создать на одном физическом сервере несколько логических серверов, возможно, принадлежащих разным организациям и имеющих собственные адреса IP. Каждый такой адрес может быть отображен в доменной базе адресов на отдельное доменное имя, в результате чего создается полная иллюзия наличия нескольких отдельных серверов.
Заметим, что виртуальные серверы создаются обычно на серверах крупных поставщиков услуг Internet.
Последняя страница блокнота настроек параметров сервиса WWW называется Logging и представлена на рис. 9.28.

Рис. 9.28. Страница Logging блокнота настроек параметров сервиса WWW
При необходимости вы можете включить протоколирование операций, выполняемых сервером WWW. Страница Logging позволяет вам задать периодичность создания нового файла журнала, а также указать каталог, в котором будет хранится журнал.
Если сервер WWW используется совместно с базой данных, вы можете включить переключатель log to SQL/ODBC Database и выполнить протоколирование операций, выполняемых над этой базой данных.
Администрирование
Для администрирования сервера Personal Web Server разработчики из Microsoft не стали создавать отдельное приложение. Вместо этого они использовали технологию, основанную на применении расширений ISAPI самого сервера Personal Web Server.Откройте блокнот Personal Web Server Properties на странице Administration, как это было описано в предыдущем разделе, и нажмите кнопку Administration. В результате будет запущен навигатор Microsoft Internet Explorer, в окне которого появится главная страница системы администрирования (рис. 9.11).

Рис. 9.11. Главная страница системы администрирования сервера Personal Web Server
Если сделать двойной щелчок левой клавишей мыши по ссылке WWW Administration, в окне навигатора Microsoft Internet Explorer появится документ HTML с нарисованным блокнотом (рис. 9.12). С помощью страниц этого блокнота вы можете настраивать различные параметры сервера.

Рис. 9.12. Страница Service блокнота настройки параметров сервера в документе HTML
В полях Connection timeout и Maximum Connections вы можете задать, соответственно, время ожидания соединения (в секундах) и максимальное количество соединений, которые могут быть установлены с сервером.
Переключатели, расположенные в поле Password Authentication позволяют выбрать режим аутентификации, то есть проверки идентификатора пользователя. Если включен переключатель Basic, пароли передаются по сети в незашифрованном виде, поэтому они могут быть легко перехвачены злоумышленниками. По умолчанию используется режим передачи зашифрованных паролей (переключатель Windows NT Challenge/Response). Этот режим работает только в том случае, если ваш сервер подключен к локальной сети, в которой есть домен Microsoft Windows NT.
Если включен переключатель Allow anonymous, к серверу может подключиться пользователь с любым идентификатором (анонимный пользователь). Такой режим установлен по умолчанию.
В поле Comment вы можете вставить короткую строку описания сервера.
Страница Directories блокнота настройки параметров сервера, показанная на рис. 9.13, позволяет выполнить настройку путей к каталогам, в которых расположены документы HTML и программные расширения сервера.

Рис. 9.13. Страница Directories блокнота настройки параметров сервера
Каталог C:\WebShare\wwwroot является корневым каталогом сервера Personal Web Server, в который вы должны поместить свои файлы документов HTML. Эти файлы могут лежать как в самом корневом каталоге, так и в его подкаталогах.
Программные расширения сервера располагаются в каталоге C:\WebShare\scripts, который создается по умолчанию при установке сервера. В этот каталог вы должны записать свои программы CGI или приложения ISAPI.
Каталог C:\Program Files\WebSvr содержит подкаталоги Docs, Htmla и Htmlascr. В первом из них находится документация на сервер Personal Web Server в виде документов HTML. Каталоги Htmla и Htmlascr содержат, соответственно, документы HTML с графическими изображениями и расширения сервера ISAPI, которые используются для администрирования сервера.
Теперь о переключателях Enable Default Document и Directory Browsing Allowed.
Если включен переключатель Enable Default Document (а он включен по умолчанию), пользователь может не указывать навигатору имя документа HTML, ограничившись только заданием адреса URL каталога. В этом случае в окно навигатора будет загружен документ, имя файла которого указано в поле Default Document.
Планируя содержимое каталогов, вы должны предусмотреть файл документа HTML, который будет загружаться по умолчанию в том случае, если пользователь не указал имя файла.
А что произойдет, если переключатель Enable Default Document выключен, а пользователь не задал имя файла, ограничившись только адресом каталога?
Это зависит от состояния переключателя Directory Browsing Allowed.
Если этот переключатель включен, в окне навигатора появится список файлов и каталогов, расположенных в указанном каталоге. Пример такого списка мы привели на рис. 9.14. В том случае, когда указанный переключатель выключен, пользователь получит сообщение об ошибке.

Рис. 9.14. Список файлов в окне навигатора
Возможно, у вас есть причины скрывать от пользователей содержимое каталогов. В этом случае вам следует отключить переключатель Directory Browsing Allowed, одновременно предусмотрев для каждого каталога документ, который будет отображаться по умолчанию.
Страница Directories блокнота настройки параметров сервера Personal Web Server позволяет вам редактировать список каталогов, доступных удаленным пользователям. Например, вы можете добавить в этот список новые каталоги, удалить имеющиеся или изменить параметры каталогов.
Для редактирования параметров каталогов вы должны сделать щелчок левой клавишей мыши по ссылке Edit, расположенной справа от нужного вам каталога. В результате в окне навигатора появится документ, позволяющий изменить параметры указанного вами каталога (рис. 9.15). Добавление нового каталога выполняется при помощи аналогичного документа, вызываемого по ссылке Add.

Рис. 9.15. Документ HTML, позволяющий изменить параметры выбранного каталога
В поле Directory вы можете указать путь к физическому каталогу. Если нажать кнопку Browse, у вас появится возможность выбрать каталог в окне навигатора.
Переключатель Home Directory позволяет указать, что данный каталог является главным (домашним) каталогом сервера и должен отображаться по умолчанию.
Переключатель Virtual Directory используется для создания так называемого виртуального каталога. На рис. 9.15 для корневого каталога указано имя виртуального каталога, состоящее из символа “/”.
Зачем нужен виртуальный каталог?
Имя виртуального каталога может использоваться в документах HTML вместо физического (например, при организации ссылок). В этом случае появляется возможность перемещения физических каталогов без изменения текста ссылающихся на них документов HTML.
С помощью переключателей группы Access вы можете определить вид доступа, разрешенного удаленным пользователям к данному каталогу. Для каталогов, содержащих обычные документы HTML разрешается доступ на чтение (включается переключатель Read) и запрещается доступ на выполнение программ (выключается переключатель Execute). Для каталогов, в которых записаны программы CGI или приложения ISAPI, наоборот, запрещается доступ на чтение и разрешается доступ на выполнение.
Страница Logging блокнота настройки параметров сервера Personal Web Server позволяет управлять процессом протоколирования событий (рис. 9.16).

Рис. 9.16. Страница Logging блокнота настройки параметров сервера Personal Web Server
Протоколирование выполняется только в том случае, если включен переключатель Enable logging. Если включить переключатель Automatically open new log, то можно выбрать интервал, с которым будет создаваться новый файл журнала. Вы можете указать, что журнал должен создаваться ежедневно (переключатель Daily), еженедельно (переключатель Weekly), ежемесячно (переключатель Monthly) или когда файл журнала достигнет заданных размеров (переключатель When the file size reaches).
В поле Log file directory указан путь к файлу журнала. Имя этого файла - Inetserver_event.log.
Ниже мы привели фрагмент содержимого файла журнала:
154.101.200.255, -, 26.01.97, 10:05:19, W3SVC, FROLOV, 154.101.200.255, 406, 278, 1379, 200, 0, GET, /Default.htm, -,
154.101.200.255, -, 26.01.97, 10:05:23, W3SVC, FROLOV, 154.101.200.255, 3884, 350, 255, 200, 0, GET, /scripts/counter.dll, 9605071636,
154.101.200.255, -, 26.01.97, 10:05:44, W3SVC, FROLOV, 154.101.200.255, 290, 293, 3660, 200, 0, GET, /htmla/htmla.htm, -,
. . .
154.101.200.255, -, 26.01.97, 10:05:48, W3SVC, FROLOV, 154.101.200.255, 1138, 349, 1277, 200, 0, GET, /htmla/bolt.gif, -,
154.101.200.255, -, 26.01.97, 10:05:52, W3SVC, FROLOV, 154.101.200.255, 4300, 355, 2445, 200, 0, GET, /HtmlaScripts/htmla.dll, http/serv,
. . .
В этом файле через запятую приведена следующая информация о выполненной операции:
Как видите, из этого файла можно извлечь информацию о том, кто и когда обращался к тем или иным файлам, расположенным в каталогах сервера, а также другие интересные сведения.
Анимация
Как мы уже говорили, формат GIF позволяет хранить в одном файле несколько графических изображений. При отображении такого файла навигаторы могут показывать эти изображения по очереди, как кадры обычного кинофильма. Подготовив достаточное количество кадров, вы можете создать небольшой фильм (или мультфильм) и разместить его в документе HTML.Аннотация
Книга представляет собой практическое руководство по созданию серверов Web в глобальной сети Internet или в глобальных корпоративных сетях Intranet. Здесь вы найдете все, что вам потребуется для создания собственных документов HTML, как статических, так и динамических.Отдельная глава посвящена установке и настройке серверов Microsoft Information Server и Microsoft Peer WebServices в среде операционной системы Windows NT, а также сервера Microsoft Personal Web Server для операционной системы Windows 95.
Мы научим вас создавать расширения серверов Web на базе интерфейсов CGI и ISAPI, что необходимо для конструирования интерактивных документов HTML.
Автоматическая перезагрузка документа
Если какой-либо документ периодически обновляется на сервере, вы можете сообщить навигатору, что этот документ надо время от времени перезагружать. Такая перезагрузка выполняется с использованием методики, которая называется client pull, что можно перевести как запрос данных со стороны клиента (то есть навигатора).Включив в заголовок документа следующую строку, вы можете заставить навигатор автоматически перезагружать документ HTML каждые три секунды:
Автоматическая загрузка другого документа
С помощью оператора можно решить такую задачу, как автоматическая загрузка заданного документа HTML через определенный интервал времени.Для чего это может потребоваться?
Например, на главной странице вашего сервера может находиться приветственное сообщение. Вы можете сделать так, что через некоторое время после появления этого сообщения навигатор автоматически загрузит другой документ, например, содержащий меню.
В приведенном ниже фрагменте через 15 секунд после загрузки текущего документа будет загружен документ с адресом http://www.my.ru/hello1.htm:
Бегущая строка
С помощью оператора , можно разместить на экране бегущую строку, например:Бегущая строка может быть использована для привлечения внимания пользователя, однако не злоупотребляйте этой возможностью - неуместная бегущая строка может раздражать пользователя и он покинет вашу страницу, так и не прочитав на ней что-нибудь важное…
Благодарности
Авторы выражают благодарность сотруднику фирмы Microsoft АО Юрию Тумашко за предоставленное в наше распоряжение программное обеспечение.В работе над книгой нам помогли сотрудники фирмы Interactive Products Inc. Максим Синев и Сергей Ноженко, у которых мы консультировались по различным вопросам, связанным с языком HTML и с разработкой программных расширений ISAPI.
Отдельную благодарность мы выражаем генеральному директору АО “ДиалогНаука” Антимонову Сергею Григорьевичу и его заместителю Лященко Юрию Павловичу за возможность размещения информации о наших книгах на сервере Web по адресу http://www.dials.ccas.ru/frolov, а также за возможность доступа к сети Internet через сервер АО “ДиалогНаука”.
Мы благодарим корректора Кустова В. С. и сотрудников издательского отдела АО “Диалог-МИФИ” Голубева О. А., Голубева А. О., Дмитриеву Н. В., Виноградову Е. К., Кузьминову О. А.
Что лучше - GET или POST
Метод GET обычно используется для обработки небольших форм, так как навигаторы накладывают ограничения для размера данных, передаваемых через переменную среды QUERY_STRING.В этом отношении метод POST является более предпочтительным, так как не накладывает на размер передаваемых данных никаких ограничений. Только метод POST пригоден для передачи файлов из локального компьютера через навигатор в сервер WWW.
Что такое сеть Internet
Как вы, наверное, знаете, глобальная сеть Internet объединяет миллионы компьютеров, расположенные в разных странах по всему свету. Большинство таких компьютеров - это рабочие станции конечных пользователей, подключенные к сети Internet через модем и обычную телефонную линию. Другие компьютеры выполняют функцию серверов и служат хранилищами информации в сети. Серверы соединяют между собой, как правило, высокоскоростными и дорогостоящими каналами связи, например, каналами ISDN, оптоволоконными или спутниковыми каналами.Конечные пользователи обычно подключаются к одному из серверов, расположенных в том же городе, что и они сами. При этом соединение через телефонную сеть получается локальным, а не междугородним, что стоит существенно дешевле. Что же касается соединения серверов между собой, то каналы связи, которые для этого используются, арендуются владельцами серверов, поэтому конечным пользователям не нужно за них платить.
На рис. 1.1 мы воспроизвели схему основных компонент глобальной сети Internet, взяв ее из упомянутого выше 23 тома “Библиотеки системного программиста”.

Рис. 1.1. Основные компоненты глобальной сети Internet
Из этой схемы видно, что существуют различные возможности для подключения компьютеров к сети Internet.
Обычные “одиночные” пользователи подключаются к сети через модем. Пользователи локальной сети могут также подключаться к Internet через свои модемы, однако чаще такое подключение выполняется через сервер, расположенный в этой локальной сети. Сервер может быть подключен к Internet через модем, адаптер линии ISDN, оптоволоконную линию связи или спутниковую линию.
Заметим, что не существует никакого администратора сети Internet. Никакая организация не отвечает за работоспособность этой сети в целом, так как фактически сеть состоит из большого количества самостоятельных сетей, отдельных серверов и рабочих станций, принадлежащим различным фирмам и частным лицам. Тем не менее, сеть Internet работает, и достаточно надежно для того, чтобы ее можно было использовать в коммерческих целях.
Какова скорость передачи данных в сети Internet?
Разная. Здесь все зависит от пропускной способности и загруженности каналов связи, от производительности и загруженности серверов. Если вы приобрели современный модем со скоростью передачи данных 33600 бит/с, то совсем не обязательно, что вы будете получать информацию из сети Internet именно с этой скоростью. Некоторые серверы так загружены, что способны отдавать данные со скоростью не более 100-200 байт/с, и никакой даже самый дорогой модем тут не поможет. Однако в среднем может быть достигнута скорость 1-2 Кбайт/с, что вполне достаточно для многих приложений.
Цвет в документах HTML
Цветные страницы выглядят намного привлекательнее серых или черно-белых. Язык HTML позволяет вам указывать цвет фона, текста, полей ссылок на другие документы HTML и так далее.Для выделения заголовков и отдельных слов в тексте вы можете использовать цвет. При этом, однако, не следует увлекаться, так как стремление использования максимально возможного количества цветов приведет к тому, что ваши страницы будут выглядеть слишком пестрыми. Кроме того, на внешний вид страницы влияет цветовое разрешение, установленное в компьютере пользователя. Если пользователь работает с видеоадаптером VGA (а такое еще встречается, особенно среди пользователей старых и блокнотных компьютеров), он не сможет воспринять всю цветовую гамму многоцветных документов HTML, рассчитанных на режимы с высоким цветовым разрешением. Поэтому используйте цвет только там, где он действительно необходим для улучшения внешнего вида страницы.
Цвет в других элементах документа HTML
Многие операторы документа HTML позволяют задавать цвет определяемых ими элементов. Это ссылки на другие страницы HTML, таблицы, рамки, разделительные линии и так далее. Как правило, во всех операторах для указания цвета используется только что описанный нами параметр COLOR. По мере изучения языка HTML вы научитесь задавать цвет всех элементов документа HTML.Физическое форматирование символов
В языке HTML определены операторы так называемого физического форматирования символов текста. Эти операторы определяют внешний вид символов явным образом.Наряду с операторами физического форматирования существуют операторы логического форматирования, которые мы опишем в следующем разделе. Эти операторы предназначены для указания семантического (смыслового) назначения оформляемого текста. Анализируя операторы логического форматирования, навигатор самостоятельно подбирает для этого текста шрифтовое оформление.
Ниже мы перечислили операторы физического форматирования:
| Оператор | Описание | ||
| , | Выделение жирным шрифтом | ||
| , | Выделение наклонным шрифтом | ||
| , | Выделение подчеркиванием | ||
| Выделение перечеркиванием | |||
| , | Оформление шрифтом с фиксированной шириной букв | ||
| , | Текст с крупным размером букв | ||
| , | Текст с малым размером букв | ||
| | Мигающий текст | ||
| , | Подстрочный индекс | ||
| , | Надстрочный индекс |
Формат GIF
Формат GIF был разработан пользователями сети CompuServe и в настоящее время стал очень популярен. Несмотря на то что изображения, хранящиеся в этом формате, не могут иметь более 256 цветов, формат GIF обладает возможностями, которые делают его незаменимым в целом ряде случаев.Во-первых, в формате GIF используются алгоритмы сжатия изображения без потерь качества. Поэтому этот формат как нельзя лучше подходит для хранения копий экранов или штриховых рисунков, содержащих большие однотонные площади.
Во-вторых, вы можете существенно уменьшить размер графического файла, записав в него сокращенную цветовую палитру вместо полной 256-цветной.
В-третьих, размещая в документах HTML специальным образом подготовленные изображения GIF, вы можете получить эффект прозрачности. Части изображения могут быть прозрачными, поэтому видимая форма изображения может отличаться от квадратной или прямоугольной.
В-четвертых, формат GIF и только формат GIF позволяет создавать анимационные графические изображения, оживляющие внешний вид документа HTML.
И, наконец, в пятых, формат GIF позволяет создавать файлы с чересстрочным (interlaced) изображением. Что это такое?
Строки чересстрочных изображений GIF располагаются не подряд, а по очереди. Вначале в этом файле находятся строки, номера которых кратны восьми, затем - четырем и так далее. Чересстрочное изображение проявляется на экране навигатора постепенно, увеличивая свою четкость по мере получения новых порций данных. Это дает пользователю возможность оценить содержимое графического изображения до момента его полной загрузки. Если изображение вам не нужно, вы можете отказаться от его загрузки до полного завершения процесса и тем самым сэкономить время.
Как устроен файл GIF?
Файл в формате GIF версии 89a состоит из блоков нескольких типов, два из которых являются обязательными, а остальные - дополнительными. Обязательные блоки - это блоки заголовка и блоки изображения. Дополнительно файл GIF может содержать блоки комментария, текстовые и управляющие блоки, а также блоки данных, содержащие произвольную информацию.
В блоке заголовка расположена палитра и сведения о размерах области, в которой желательно отображать содержимое файла. Что же касается палитры, то в файле GIF может быть определена одна глобальная палитра, которая используется для всех графических изображений, записанных в файле, или несколько локальных палитр для отдельных изображений.
В одном файле GIF может быть один или несколько блоков изображений. Если вы создаете прозрачные или анимационные изображения, вам будет нужно подготовить несколько изображений и записать их в файл.
В блок комментария вы можете записать текст, описывающий изображение, или сведения о правах на изображение. Содержимое блока комментария не появится на экране во время отображения файла GIF, однако его можно увидеть непосредственно в файле, например, с помощью программы просмотра содержимого файла, встроенного в оболочку Norton Commander.
Что же касается текстовых блоков, то расположенный в них текст будет выведен на экран поверх изображения. При подготовке текстового блока вы можете указать цвет и расположение текста.
Создавая управляющие блоки, вы можете определить цвет в изображении или тексте как прозрачный. При отображении такого изображения прозрачные фрагменты не будут закрывать рисунок, который используется в качестве фона.
Дополнительные блоки данных с произвольной информацией могут использоваться приложениями, отображающими изображение.
Формат JPEG
Хотя исторически формат GIF появился раньше, сначала мы расскажем о формате JPEG. Этот формат имеет особенности, делающие привлекательным его использование в документах HTML, особенно для отображения многоцветных фотографий.Прежде всего, формат JPEG допускает сжатие графической информации с потерями. Подготавливая файл в формате JPEG, вы можете указать допустимый процент потери качества. Чем больше этот процент, тем меньший объем дискового пространства потребуется для хранения файла и, что самое главное, тем меньшее время потребуется удаленному пользователю для загрузки изображения.
Минимизация размера графического изображения без существенных потерь качества - очень важная процедура. Дело здесь в том, что в среднем информация передается через сеть Internet со скоростью примерно 1 Кбайт в секунду, поэтому на загрузку больших изображений может уйти слишком много времени. Поэтому даже и не думайте о том, чтобы разместить в документе HTML цветную фотографию, занимающую на диске 1 Мбайт - посчитайте сами, сколько времени эта фотография будет передаваться пользователю.
Реальные объемы изображений, которые можно использовать, лежат в пределах от нескольких Кбайт до нескольких десятков Кбайт. Если же существует принципиальная необходимость размещения в документе HTML графического изображения высокого разрешения, занимающего много места, вы можете создать в документе ссылку на это изображение в виде небольшой пиктограммы. О том как это сделать, мы расскажем позже.
Другое преимущество формата JPEG заключается в том, что он позволяет хранить изображения с высоким цветовым разрешением (например, содержащие 16 млн. цветов).
Есть ли у формата JPEG недостатки?
Конечно есть, а как же без них.
Наиболее заметный недостаток алгоритма сжатия с потерей качества сказывается при попытке сжать изображение с большим количеством четких контуров, например, копий экрана или штриховых рисунков. Даже при небольших потерях качества контуры размываются, что может оказаться совершенно неприемлемо. Поэтому мы рекомендуем применять формат JPEG только для хранения фотографий или рисунков с плавными переходами цветов и яркостей.
Функция GetExtensionVersion
Насколько проста реализация функции GetExtensionVersion вы можете судить по следующему фрагменту кода, взятому нами из исходных текстов приложения FILEUPL (это приложение будет полностью рассмотрено позже):// =============================================================
// Функция GetExtensionVersion
// =============================================================
BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO *pVersion)
{
pVersion->dwExtensionVersion =
MAKELONG(HSE_VERSION_MINOR,HSE_VERSION_MAJOR);
lstrcpyn(pVersion->lpszExtensionDesc,
"Remote File Upload", HSE_MAX_EXT_DLL_NAME_LEN);
return TRUE;
}
При вызове функции GetExtensionVersion передается указатель на структуру типа HSE_VERSION_INFO. Эта структура и указатель на нее LPHSE_VERSION_INFO определены в файле httpext.h следующим образом:
#define HSE_MAX_EXT_DLL_NAME_LEN 256
typedef struct _HSE_VERSION_INFO
{
DWORD dwExtensionVersion;
CHAR lpszExtensionDesc[HSE_MAX_EXT_DLL_NAME_LEN];
} HSE_VERSION_INFO, *LPHSE_VERSION_INFO;
Константы HSE_VERSION_MINOR и HSE_VERSION_MAJOR указывают текущую версию интерфейса расширения ISAPI и также определены в файле httpext.h:
#define HSE_VERSION_MAJOR 2 // верхний номер версии
#define HSE_VERSION_MINOR 0 // нижний номер версии
Функция GetServerVariable
Прототип функции GetServerVariable определен в структуре EXTENSION_CONTROL_BLOCK, описанной нами ранее:BOOL (WINAPI * GetServerVariable)(HCONN hConn,
LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSize);
Через параметр hConn вы должны передать этой функции идентификатор канала, полученный через поле ConnID структуры EXTENSION_CONTROL_BLOCK.
Параметр lpszVariableName должен содержать указатель на строку имени переменной, содержимое которой необходимо получить. Это содержимое будет записано функцией в буфер, адрес которого передается через параметр lpvBuffer, а размер - через параметр lpdwSize.
Ниже мы перечислили возможные значения строк, передаваемых через параметр lpszVariableName:
Переменная среды AUTH_TYPE содержит тип идентификации, который применяется сервером.
В этой переменной перечислены типы данных MIME, которые могут быть приняты навигатором от сервера WWW.
Количество байт данных, которые расширение ISAPI должно получить от навигатора.
Тип данных, присланных навигатором.
Путь к виртуальному каталогу, в котором находится библиотека DLL расширения ISAPI.
Физический путь к библиотеки DLL расширения ISAPI.
Строка параметров, указанная в форме или операторе ссылки . Эта строка указывается после адреса URL библиотеки DLL расширения ISAPI вслед за разделительным символом “?”.
Адрес IP узла, на котором работает навигатор удаленного пользователя.
Доменное имя узла, на котором работает навигатор удаленного пользователя. Если эта информация недоступна (например, для узла не определен доменный адрес), то вместо доменного имени указывается адрес IP, как в переменной REMOTE_ADDR.
Имя пользователя, которое используется навигатором для аутентификации.
Имя пользователя до обработки фильтром ISAPI, которое используется навигатором для аутентификации.
Метод доступа, который используется для передачи данных от навигатора серверу WWW.
В эту переменную записывается путь к виртуальному каталогу и имя библиотеки DLL расширения ISAPI. Анализируя эту переменную, расширение ISAPI может определить путь к своему загрузочному файлу.
Доменное имя сервера WWW или адрес IP сервера WWW, если доменное имя недоступно или не определено.
Имя и версия протокола, который применяется для выполнения запроса к расширению ISAPI.
Номер порта, на котором навигатор посылает запросы серверу WWW.
Если обработка запроса выполняется через защищенный порт, в этой строке записано значение 1, а если через незащищенный - значение 0.
Название и версия программного обеспечения сервера WWW. Версия следует после названия и отделяется от последнего символом “/”.
Строка, закрытая двоичным нулем, в которую записаны значения всех переменных, имеющих отношение к протоколу HTTP. Это, например, такие переменные как HTTP_ACCEPT, HTTP_CONNECTION, HTTP_USER_AGENT и так далее.
Извлекать содержимое отдельных переменных ваша программа должна самостоятельно. При этом следует учесть, что названия переменных отделены от их значений символом двоеточия “:”, а поля переменных разделены символом перевода строки.
Обратите внимание, что названия этих строк почти совпадают с названиями переменных среды, создаваемых для программ CGI, однако совпадение все же не полное.
В случае успешного завершения функция GetServerVariable возвращает значение TRUE, а при возникновении ошибки - значение FALSE. Код ошибки можно определить с помощью функции GetLastError, вызвав ее сразу после функции GetServerVariable. Эта функция может вернуть в данном случае следующие коды ошибок:
|
Код ошибки |
Описание |
|
ERROR_INVALID_INDEX |
Неправильное имя переменной, передаваемой через параметр lpszVariableName |
|
ERROR_INVALID_PARAMETER |
Неправильное значение параметра hConn |
|
ERROR_INSUFFICIENT_BUFFER |
Буфер, адрес которого указан с помощью параметра lpvBuffer, слишком мал. Необходимый размер буфера записывается по адресу, который был передан функции через параметр lpdwSize |
|
ERROR_MORE_DATA |
Буфер, адрес которого указан с помощью параметра lpvBuffer, слишком мал. В результате данные были прочитаны частично, причем размер буфера, необходимый для чтения всех данных, неизвестен |
|
ERROR_NO_DATA |
Данные не были получены |
CHAR szTempBuf[4096];
DWORD dwSize;
dwSize = 4096;
lpECB->GetServerVariable(lpECB->ConnID,
(LPSTR)"ALL_HTTP", (LPVOID)szTempBuf, &dwSize);
strcat(szBuff, szTempBuf);
Функция HttpExtensionProc
Теперь рассмотрим вторую функцию, которую должна экспортировать библиотека DLL расширения ISAPI. Она называется HttpExtensionProc и имеет следующий прототип:DWORD WINAPI HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB);
Функция HttpExtensionProc получает единственный параметр - указатель на структуру типа EXTENSION_CONTROL_BLOCK, определенную в файле httpext.h:
typedef struct _EXTENSION_CONTROL_BLOCK
{
DWORD cbSize; // размер структуры в байтах
DWORD dwVersion; // версия спецификации ISAPI
HCONN ConnID; // идентификатор канала
DWORD dwHttpStatusCode; // код состояния HTTP
CHAR lpszLogData[HSE_LOG_BUFFER_LEN]; // текстовая строка,
// закрытая двоичным нулем, в которой находится информация
// протоколирования, специфичная для данного расширения
LPSTR lpszMethod; // переменная REQUEST_METHOD
LPSTR lpszQueryString; // переменная QUERY_STRING
LPSTR lpszPathInfo; // переменная PATH_INFO
LPSTR lpszPathTranslated; // переменная PATH_TRANSLATED
DWORD cbTotalBytes; // полный размер данных, полученных от
// навигатора
DWORD cbAvailable; // размер доступного блока данных
LPBYTE lpbData; // указатель на доступный блок данных
// размером cbAvailable байт
LPSTR lpszContentType; // тип принятых данных
// Функция GetServerVariable для получения значения переменных
BOOL (WINAPI * GetServerVariable)(HCONN hConn,
LPSTR lpszVariableName, LPVOID lpvBuffer, LPDWORD lpdwSize);
// Функция WriteClient для посылки данных удаленному пользователю
BOOL (WINAPI * WriteClient)(HCONN ConnID,
LPVOID Buffer, LPDWORD lpdwBytes, DWORD dwReserved);
// Функция ReadClient для получения данных от удаленного
// пользователя
BOOL (WINAPI * ReadClient) (HCONN ConnID,
LPVOID lpvBuffer, LPDWORD lpdwSize);
// Вспомогательная функция ServerSupportFunction
// для выполнения различных операций
BOOL (WINAPI * ServerSupportFunction)(HCONN hConn,
DWORD dwHSERRequest, LPVOID lpvBuffer,
LPDWORD lpdwSize, LPDWORD lpdwDataType);
} EXTENSION_CONTROL_BLOCK, *LPEXTENSION_CONTROL_BLOCK;
Рассмотрим отдельные поля этой структуры.
В самом начале структуры EXTENSION_CONTROL_BLOCK находится поле cbSize, в которое при вызове расширения сервер записывает размер структуры в байтах.
Поле dwVersion содержит номер версии расширения ISAPI. Верхнее и нижнее значения номера версии можно получить, соответственно, при помощи макрокоманд HIWORD и LOWORD.
В поле ConnID сервер записывает идентификатор канала, созданного для расширения. Это поле вы не должны изменять.
Поле dwHttpStatusCode должно заполняться расширением ISAPI. Вы должны записать сюда результат завершения операции (код состояния транзации). В случае успеха в это поле записывается значение 200 (как указано в спецификации HTTP).
Поле lpszLogData предназначено для записи сообщения о выполнении транзакции в журнал сервера WWW. Это сообщение должно быть в виде текстовой строки, закрытой нулем. Размер строки в байтах не должен превышать значения HSE_LOG_BUFFER_LEN.
Поле lpszMethod заполняется сервером и содержит название метода передачи данных от удаленного пользователя серверу в виде текстовой строки, закрытой двоичным нулем. Расширения ISAPI используют те же самые методы, что и программы CGI - метод GET и метод POST. Проводя аналогию с программами CGI дальше, скажем, что поле lpszMethod эквивалентно переменной среды с именем REQUEST_METHOD, создаваемой для программы CGI.
Аналогично, поле lpszQueryString соответствует переменной среды с именем QUERY_STRING. В это поле записываются данные, принятые от удаленного пользователя методом GET.
В поле lpszPathInfo записывается виртуальный путь к программному файлу библиотеки DLL расширения ISAPI. Напомним, что аналогичная информация для программ CGI передавалась через переменную среды с именем PATH_INFO.
Это поле содержит физический путь к программному файлу библиотеки DLL расширения ISAPI. Оно соответствует переменной среды с именем PATH_TRANSLATED, создаваемой для программ CGI.
В поле cbTotalBytes записывается общее количество байт данных, которое необходимо получить от удаленного пользователя. Часть этих данных (размером не более 48 Кбайт) считывается сервером автоматически и становится доступной сразу после того как функция HttpExtensionProc получит управление. Остальные данные необходимо дочитать в цикле при помощи функции ReadClient, о которой мы еще будем говорить.
В поле cbAvailable записывается размер блока данных, полученных от удаленного пользователя автоматически. Как мы только что сказали, размер этого блока не может превышать 48 Кбайт. Этого, однако, вполне достаточно для обработки данных, полученных от форм обычного размера.
Указатель на область памяти, в которую записан сервером полученный от удаленного пользователя блок данных размером cbAvailable байт.
Поле lpszContentType содержит тип принятых данных, например, text/html.
Помимо полей данных, структура EXTENSION_CONTROL_BLOCK содержит указатели на функции. С помощью этих функций расширение ISAPI может выполнять различные операции, такие как прием данных от удаленного пользователя.
Поле GetServerVariable содержит указатель на функцию, с помощью которой расширение ISAPI может получить информацию, которая доступна программам CGI через переменные среды, описанные нами в предыдущей главе этой книги.
В поле WriteClient находится адрес функции, которую расширение ISAPI должно использовать для посылки данных удаленному пользователю. Таким образом, вместо того чтобы записывать данные в стандартный поток вывода STDOUT, как это делает программа CGI, приложение ISAPI посылает данные с помощью функции WriteClient.
С помощью функции, адрес которой передается в поле ReadClient, приложение может дочитать дополнительные данные, не поместившиеся в буфер предварительного чтения, имеющий адрес lpbData и размер, не превышающий 48 Кбайт. Аналогичную операцию приема данных от пользователя выполняет программа CGI в случае применения метода передачи данных POST. Отличие заключается в том, что программа CGI получает данные через стандартный поток ввода STDIN, а расширение ISAPI берет эти данные из буфера предварительного чтения и при необходимости дочитывает данные функцией ReadClient.
С помощью функции, адрес которой передается через поле ServerSupportFunction, расширение ISAPI может выполнять различные действия, такие как посылка стандартного заголовка протокола HTTP и некоторые другие.
При успешном завершении функция HttpExtensionProc должна вернуть значение HSE_STATUS_SUCCESS, а при ошибке - значение HSE_STATUS_ERROR. Соответствующие константы определены в файле httpext.h.
Функция ReadClient
Прототип функции ReadClient находится в определении структуры EXTENSION_CONTROL_BLOCK и выглядит следующим образом:BOOL (WINAPI * ReadClient) (HCONN ConnID,
LPVOID lpvBuffer, LPDWORD lpdwSize);
Через параметр hConn этой функции надо передать идентификатор канала, полученный через поле ConnID структуры EXTENSION_CONTROL_BLOCK.
Функция ReadClient читает данные в буфер, адрес которого передается через параметр lpvBuffer, а размер - через параметр lpdwSize. В случае успеха функция возвращает значение TRUE, а при ошибке - значение FALSE. Код ошибки можно получить при помощи функции GetLastError.
Работа с функцией ReadClient имеет некоторые особенности.
Когда расширение ISAPI получает управление, через структуру типа EXTENSION_CONTROL_BLOCK передается адрес предварительно прочитанного блока данных, полученного от удаленного пользователя. Как вы знаете, адрес и размер этого блока данных указаны, соответственно, в полях lpbData и cbAvailable структуры EXTENSION_CONTROL_BLOCK.
Однако размер предварительно прочитанных данных не может превышать 48 Кбайт. Если все данные не поместились в буфер предварительного чтения, их необходимо дочитать функцией ReadClient. При этом следует использовать следующий алгоритм.
Прежде всего следует сравнить размер предварительно считанных данных с полным размером данных, которые нужно считать (этот размер передается в поле cbTotalBytes структуры EXTENSION_CONTROL_BLOCK).
Если все данные уже были считаны предварительно, функцию ReadClient вызывать не нужно. В том случае, когда значение, передаваемое через поле cbTotalBytes, превышает значение cbAvailable, вы должны воспользоваться функцией ReadClient для того чтобы прочесть (cbTotalBytes - cbAvailable) байт данных от пользователя.
Заметим, что функция ReadClient не будет читать заново данные, предварительно прочитанные в буфер lpbData. Она прочитает только оставшиеся данные, причем не исключено, что для чтения оставшихся данных эту функцию придется вызывать в цикле несколько раз. Причина этого заключается в том, что функция ReadClient не обязательно сможет прочитать все оставшиеся данные за один прием.
После успешного завершения чтения функция ReadClient записывает размер прочитанного блока данных в переменную, адрес которой передается через параметр lpdwSize. Если при первом вызове значение этого размера меньше величины (cbTotalBytes - cbAvailable), вы должны вызвать функцию ReadClient еще один или несколько раз для чтения оставшихся данных.
Пример использования функции ReadClient вы найдете в разделе “Приложение FILEUPL”. Там мы привели исходные тексты расширения ISAPI, позволяющее использовать сервер WWW довольно необычным способом - для получения файлов от удаленных пользователей и записи их на диск сервера. Так как размеры передаваемых файлов могут быть значительны, приложение FILEUPL вызывает функцию ReadClient в цикле.
Функция ServerSupportFunction
Прототип функции ServerSupportFunction, определенный в структуре типа EXTENSION_CONTROL_BLOCK, приведен ниже:BOOL (WINAPI * ServerSupportFunction)(HCONN hConn,
DWORD dwHSERRequest, LPVOID lpvBuffer,
LPDWORD lpdwSize, LPDWORD lpdwDataType);
Через параметр hConn функции ServerSupportFunction передается идентификатор канала, полученный через поле ConnID структуры EXTENSION_CONTROL_BLOCK.
С помощью параметра dwHSERRequest вы можете задать один из нескольких кодов запроса, определяющих операцию, выполняемую этой функцией.
Через параметр lpvBuffer передается размер буфера, который используется при выполнении операции. Размер этого буфера должен быть записан в переменной типа DWORD, адрес которой передается через параметр lpdwSize. После выполнения операции передачи данных в эту переменную будет записан размер успешно переданного блока данных.
Параметр lpdwDataType используется для указания дополнительной строки заголовка или дополнительных данных, которые будут добавлены к заголовку, передаваемому удаленному пользователю. Если для параметра lpdwDataType указать значение NULL (что допустимо), к заголовку будут добавлены символы конца строки “\r\n”.
Какие операции можно выполнять при помощи функции ServerSupportFunction?
Ниже мы привели список возможных значений параметра dwHSERRequest, определяющего код выполняемой операции:
Эта операция предназначена для посылки удаленному пользователю стандартного заголовка HTTP. При необходимости добавления других заголовков следует воспользоваться параметром lpdwDataType. В качестве дополнительного заголовка вы можете указать любую строку, закрытую символами конца строки “\r\n” и двоичным нулем.
Если ваше расширение ISAPI динамически формирует документ HTML и посылает его пользователю, то ей не нужно вызывать функцию WriteClient. Все необходимые для этого действия можно сделать при помощи одной только функции ServerSupportFunction. Ниже мы показали фрагмент кода, в котором эта функция используется для посылки документа HTML, подготовленного заранее в буфере szBuff:
CHAR szBuff[4096];
wsprintf(szBuff,
"Content-Type: text/html\r\n\r\n"
"
"
Hello from ISAPI Extension!
\n");strcat(szBuff, "
Заголовок документа
");strcat(szBuff, "
");
strcat(szBuff, "");
lpECB->ServerSupportFunction(lpECB->ConnID,
HSE_REQ_SEND_RESPONSE_HEADER, NULL, NULL, (LPDWORD)szBuff);
Заметим, однако, что функция ServerSupportFunction не позволяет посылать двоичные данные. Для посылки двоичных данных вы обязательно должны использовать функцию WriteClient.
Используя операцию HSE_REQ_SEND_URL, расширение ISAPI может послать удаленному пользователю данные, заданные адресом URL, как будто бы эти данные были запрошены непосредственно пользователем по этому адресу URL. Такая возможность удобна для посылки либо динамически созданных данных, либо для посылки предварительно подготовленных данных.
Адрес URL должен быть указан в виде текстовой строки, закрытой двоичным нулем, через параметр lpvBuffer. Размер строки вы должны указать в параметре lpdwSize. Что же касается параметра lpdwDataType, то при выполнении данной операции этот параметр игнорируется.
Посылка сообщения с номером 302 (URL Redirect). Адрес URL указывается аналогично тому, как это делается при выполнении операции HSE_REQ_SEND_URL.
Преобразование логического адреса URL в физический. Адрес логического пути передается через параметр lpvBuffer. По этому же адресу записывается результат преобразования. Размер буфера при вызове функции задается как обычно с помощью параметра lpdwSize. После преобразования переменная типа DWORD, адрес которой указан параметром lpdwSize, будет содержать длину строки результата преобразования.
В том случае, когда расширение ISAPI оставляет канал открытым для выполнения длительной обработки данных, с помощью этой команды можно сообщить серверу о завершении обработки. Все параметры функции ServerSupportFunction при указании этой команды игнорируются.
Функция WriteCilent
Прототип функции WriteClient, взятый из определения структуры EXTENSION_CONTROL_BLOCK, приведен ниже:BOOL (WINAPI * WriteClient)(HCONN ConnID,
LPVOID Buffer, LPDWORD lpdwBytes, DWORD dwReserved);
Через параметр hConn функции WriteClient передается идентификатор канала, полученный через поле ConnID структуры EXTENSION_CONTROL_BLOCK.
Функция WriteClient посылает удаленному пользователю данные из буфера Buffer, причем размер передаваемого блока данных должен быть записан в переменную типа DWORD, адрес которой передается через параметр lpdwBytes. Параметр dwReserved зарезервирован для дальнейших расширений возможностей функции.
В случае успеха функция возвращает значение TRUE, а при ошибке - значение FALSE. Код ошибки можно получить при помощи функции GetLastError.
Заметим, что после посылки данных функция WriteClient записывает в переменную, адрес которой был ей передан через параметр lpdwBytes, количество успешно переданных байт данных. В отличие от функции ReadClient, функция WriteClient посылает данные за один прием, поэтому нет необходимости вызывать ее в цикле. Если же эта функция смогла передать только часть данных, то это означает, что произошла ошибка.
Использование графики в ссылках
Ссылки в виде текстовых строк удобны, так как после посещения соответствующих страниц они меняют свой цвет. Однако более привлекательно выглядят ссылки, оформленные с использованием графических изображений.Для выполнения такого оформления у вас есть две возможности.
Во-первых, вы можете вставить между операторами и графическое изображение небольшого размера. При этом оно будет использовано как чувствительная область. Если сделать щелчок левой клавишей мыши по этой области, произойдет загрузка объекта, указанного в ссылке.
Во-вторых, для организации ссылок можно применить так называемые сегментированные графические изображения (image maps). Такие изображения разделяются на несколько чувствительных областей, с каждой из которых при помощи отдельного текстового файла связывается та или иная ссылка.
Рассмотрим обе эти возможности.
Изменение цвета фона документа HTML
По умолчанию навигаторы отображают фон документов HTML серым цветом. С помощью параметра BGCOLOR оператора вы можете изменить цвет фона документа HTML, значительно улучшив его внешний вид:Другая возможность оформления заключается в использовании растровых изображений в качестве фона. Об этом мы расскажем позже.
Изменение цвета текста
Цвет текста легко изменить в операторе , задавая параметр COLOR. В приведенном ниже фрагменте документа текстовая строка отображается красным цветом:Красный цвет
Здесь мы использовали символическое обозначение цвета.
Заметим, что в спецификации языка HTML версии 3.2 допускается определение цвета в операторе
Листинг 2.5. Файл chap2\color.htm
Серебряный цвет
Если просмотреть этот документ в среде навигатора Microsoft Internet Explorer, строка “Красный цвет” будет действительно отображаться красным цветом на желтом фоне. Навигатор Netscape Navigator покажет эту строку черным цветом.
Изменение начертания шрифта
Очень часто для выделения отдельных предложений, слов или символов используется изменение начертания шрифта. При этом можно указывать наклонный, утолщенный, подчеркнутый или перечеркнутый шрифт, шрифт с малым или большим размером символов, шрифт с мигающими символами, шрифт для отображения надстрочных или подстрочных индексов и так далее. В ряде случаев вы можете указать даже название шрифта, такое например, как Arial или Times New Roman. Однако, как мы уже говорили, нельзя рассчитывать, что навигатор пользователя сможет отобразить текст указанным вами шрифтом - этот шрифт может отсутствовать в системе пользователя.Изменение размера шрифта
Шрифт увеличенного размера применяется, как правило, для выделения заголовков или важных слов в тексте. Второстепенная информация для экономии места часто оформляется шрифтом уменьшенного размера.В наших первых документах HTML мы не указывали размер шрифта, поэтому использовался тот размер, который был установлен по умолчанию при настройке навигатора. Как устанавливается этот размер?
Документы HTML обычно не содержат ссылок на название конкретного шрифта, такое, например, как Arial или Times New Roman. К тому же, в документах HTML не указывается точный размер шрифта в пунктах. Причина этого заключается в том, что разработчик документа HTML не может знать, какие шрифты используются для просмотра документа.
Пользователи могут работать в операционной системе Microsoft Windows, IBM OS/2 Warp или на компьютере Macintosh, они могут иметь различные наборы шрифтов. Поэтому нет смысла указывать название шрифта - скорее всего у пользователя шрифт с таким названием просто не установлен. В результате страница будет оформлена другим шрифтом, что может очень сильно изменить ее внешний вид.
Нельзя также указывать точный размер шрифта, так как разработчик документа HTML не знает, какое разрешение имеет экран пользователя. Если указать слишком крупный шрифт, в окне навигатора поместится очень мало информации. Если же размер шрифта окажется слишком мал, текст будет трудно прочитать.
Поэтому все навигаторы дают пользователю возможность выбрать для отображения нормального текста два шрифта из числа установленных в системе, указав размер букв. Первый шрифт имеет фиксированную ширину символов и используется для отображения такой информации, как листинги программ, а второй - это шрифт с переменной шириной букв (пропорциональный шрифт). В нашей книге шрифт с фиксированной шириной букв вы можете увидеть в листингах исходных текстов документов HTML и программ, весь остальной текст оформлен с использованием пропорционального шрифта.
Что же касается операторов языка HTML, управляющих размером шрифта, то они позволяют указать относительное изменение высоты символов, а не абсолютные значения.
Языки программирования Java, JavaScript и VBScript
Язык программирования Java был разработан фирмой Sun как платформно-независимый интерпретируемый объектно-ориентированныя язык. Этот язык был разработан на основе языка программирования С++.Вы можете создать программы Java и разместить ссылки на них в документах HTML. Такие программы являются подмножеством программ Java и называются аплетами (applets).
Программы Java, расположенные на сервере WWW, также как и органы управления ActiveX обладают большими возможностями по обработке и отображению данных, однако они более безопасны, так как не могут выполнять запись в локальные файлы. Кроме того, эти программы проще в разработке по сравнению с органами управления ActiveX и потому доступны более широкому кругу разработчиков.
Для создания программ Java вам нужны такие средства разработки, как Java Development Kit (JDK) от фирмы Sun, SDK-Java или Visual J++ от фирмы Microsoft.
Исходный текст программ, составленных на языке программирования JavaScript или VBScript вставляется непосредственно в документ HTML, поэтому для их разработки не нужны специальные средства (исключая, возможно, отладчик). Интерпретатор языка JavaScript и VBScript встроен непосредственно в навигатор Microsoft Internet Explorer (навигатор Netscape Navigator не работает с языком VBScript).
В дальнейшем мы планируем выпустить книгу, посвященную языкам программирования Java и JavaScript, получающими все большую популярность.
Как изменить внешний вид таблицы
В этом разделе мы кратко рассмотрим наиболее важные операторы языка HTML и их параметры, предназначенные для создания таблиц. Применяя эти параметры, вы можете создавать самые разные таблицы.Прежде всего, мы рассмотрим параметры оператора
, определяющими внешний вид строк и столбцов таблицы.Как работает сервер WWWСервер WWW хранит в своих каталогах текстовые файлы страниц, которые посылаются удаленным пользователям, а также все другие файлы, на которые есть ссылки в страницах (например, файлы с графическими изображениями).Текстовые файлы страниц готовятся с использованием специального языка разметки гипертекста HTML (Hyper Text Markup Language). Этот язык будет предметом подробного изучения в нашей книге. Напомним также, что введение в язык HTML вы можете найти в 23 томе “Библиотеки системного программиста”, который называется “Глобальные сети компьютеров. Практическое введение в Internet, e-mail, FTP, WWW и HTML, программирование для Windows Sockets”. Как связаться с авторамиПолную информацию о всех наших книгах серий “Библиотека системного программиста” и “Персональный компьютер. Шаг за шагом”, а также дискеты к книгам, статьи и другую информацию вы можете найти в сети Internet на серверах Web по следующим адресам:http://www.glasnet.ru/~frolov http://www.dials.ccas.ru/frolov Вы можете передать нам свои замечания и предложения по содержанию этой и других наших книг через электронную почту по адресам: frolov@glas.apc.org frolov.alexandr@usa.net Если электронная почта вам недоступна, присылайте ваши отзывы в АО “Диалог-МИФИ” по адресу: 115409, Москва, ул. Москворечье, 31, корп. 2, тел. 324-43-77 Приносим свои извинения за то что не можем ответить на каждое письмо. Мы также не занимаемся продажей и рассылкой книг, дискет и исходных текстов к нашим книгам. По этому вопросу обращайтесь непосредственно в издательство “Диалог-МИФИ”. Как выбрать формат графического файлаПодготовка и размещение графических изображений в документах HTML - это большое искусство. Однако помимо художественного вкуса, от вас потребуются знание различных технических тонкостей, от правильного учета которых во многих случаях зависит многое.Прежде всего вы должны выбрать формат файла, в котором будет храниться графическое изображение. Несмотря на то что сегодня существуют десятки различных графических форматов, практически для оформления документов HTML используются только два. Первый формат - это формат обмена графикой GIF (Graphics Interchange Format), второй - JPEG. Рассмотрим особенности этих форматов, не углубляясь в несущественные для нас технические подробности. Какой формат лучшеСовременные навигаторы позволяют работать с форматами GIF, JPEG, PCX, BMP и XBM, однако форматы PCX и BMP не обладают развитыми средствами компрессии, поэтому они практически не используются. Формат XBM родился в мире операционной системы UNIX с оболочкой X-Windows и применяется только для хранения черно-белых изображений. При размещении в документе HTML графического изображения вы должны будете сделать выбор между форматами GIF и JPEG.Если вы размещаете в документе HTML копию экрана или другое аналогичное изображение (например, изображение окна приложения или диалоговой панели), выбор сделать легко. В этом случае вам придется использовать формат GIF, так как сжатие с потерей качества приведет к неудовлетворительному результату. Аналогично, если требуется получить эффект прозрачности или анимации, выбора тоже нет - только формат GIF позволит вам создать необходимые изображения. Труднее всего сделать выбор для фотографических изображений или для рисунков с плавными изменениями цветов, так как трудно заранее сказать, какой из форматов позволит достичь минимального размера файла при приемлемом качестве изображения. Возможно, что вам придется провести эксперименты, выбирая различные степени потери качества для формата JPEG. При этом не исключено, что формат GIF даст лучшие результаты, особенно если учесть возможность использования сокращенной палитры. Логическое форматирование символовКак мы уже говорили, операторы логического форматирования предназначены для указания семантического (смыслового) назначения оформляемого текста. Они определяют не конкретный способ оформления, а указывают навигатору тип информации, подлежащей выделению. Способ выделения выбирается навигатором.Ниже мы привели список операторов логического форматирования символов с кратким описанием.
По возможности следует использовать вместо физического логическое форматирование символов, так как такое форматирование потенциально позволяет пользователю самостоятельно выбирать способ оформления указанных логических составляющих текста в соответствии со своим вкусом. К сожалению, на настоящий момент в навигаторах пользователь может только выбрать два шрифта (фиксированный и пропорциональный), а также выполнить цветовую настройку для основных компонентов отображаемого документа HTML. Локальные ссылки внутри документаЕсли длина документа HTML велика, имеет смысл организовать ссылки на его отдельные логически самостоятельные части, расположив их, например, в начале документа. Такие ссылки мы будем называть локальными ссылками в документе.Пусть вы создаете документ с именем book.htm, который состоит из нескольких глав. В начале документа вы желаете разместить оглавление, содержащее ссылки на отдельные главы. Прежде всего вы должны определить в начале каждой главы локальные метки. Для этого следует использовать оператор с параметром NAME, как это показано ниже: Первая глава. . . Содержимое главы . . . Вторая глава. . . Содержимое главы . . . Третья глава. . . Содержимое главы . . . Четвертая глава. . . Содержимое главы . . . Здесь для заголовков глав определяются метки с именами Chapter1, Chapter2, Chapter3 и Chapter4. Ссылки на созданные таким образом локальные метки выполняются также с помощью оператора , имеющего параметр HREF: Первая глава Вторая глава Третья глава Четвертая глава Когда пользователь сделает щелчок по локальной ссылке, текущий документ будет сдвинут в окне навигатора по вертикали таким образом, что строка, на которую была сделана ссылка, окажется в верхней части этого окна. Таким образом пользователь, загрузив документ, может легко перейти к просмотру любой его части. Заметим, однако, что загрузка большого документа может потребовать много времени. Поэтому следует рассмотреть возможность разделения документа на несколько файлов HTML с организацией оглавления в виде отдельного документа, содержащего только ссылки. В листинге 5. 1 мы привели исходный текст документа HTML, в котором созданы две локальные ссылки на две таблицы, имеющие различное оформление. Листинг 5.1. Файл chap5\local.htm Таблица с двойным заголовком Таблица с двойным заголовком и подписью Таблица с двойным заголовком
Таблица с двойным заголовком и подписью
Метод GETМетод GET предполагает передачу данных программе CGI через переменные среды (environment variables). Это те самые переменные среды, которые устанавливаются в операционной системе MS-DOS командой SET.Сервер WWW создает для программы CGI довольно много переменных среды. Имена и назначение всех этих переменных вы узнаете позже, а пока мы расскажем только о самых необходимых. Прежде всего, метод GET предполагает использование переменной среды с именем QUERY_STRING. Именно сюда попадают данные из полей формы. Эти данные находятся в следующем формате: “Имя1=Значение1&Имя2=Значение2&Имя3=Значение3” Здесь в качестве имен используются значения параметров NAME, задающих имена полей формы. Вместо значений подставляются данные из соответствующих полей. Сканируя содержимое текстовой строки переменной среды QUERY_STRING, программа CGI может найти в ней имя любого нужного поля и соответствующее этому имени значение. Заметим, что никакие данные от выключенных переключателей не передаются, поэтому не следует думать, что в полученной строке вы обязательно встретите имена всех полей, расположенных в форме. Адрес заданной строки переменной среды в программе, составленной на C, легко получить с помощью функции getenv: char * szQueryString; szQueryString = getenv("QUERY_STRING"); Заметим, что если вы собираетесь модифицировать строку переменной среды, то ее следует скопировать во внутренний буфер. Операционная система сервера WWW может не допустить прямого редактирования блока памяти, содержащего переменные среды. Строка, передаваемая в переменной среды QUERY_STRING, закодирована с использованием так называемой кодировки URL. В этой кодировке все символы пробелов заменяются на символы “+”. Кроме того, для представления кодов управляющих и некоторых других символов используется последовательность символов вида “%xx”, где символы “xx” представляют собой шестнадцатеричный код символа в виде двух символов ASCII. В нашей книге вы найдете исходные тексты функций, предназначенные для перекодирования информации, полученной из формы. Метод POSTПри использовании метода POST программа CGI получает данные из формы через стандартный поток ввода STDIN. Если программа CGI составлена на языке программирования C, то для получения данных она может воспользоваться такими функциями, как fread или scanf.Что же касается количества байт данных, которые нужно считать из стандартного потока ввода, то эта информация передается программе CGI через переменную среды с именем CONTENT_LENGTH. Ниже мы привели фрагмент кода для определения размера информации для ввода через стандартный поток STDIN: int Size; Size = atoi(getenv("CONTENT_LENGTH")); Входные данные могут быть затем получены, например, следующим образом: char szBuf[8196]; fread(szBuf, Size, 1, stdin); Разумеется, буфер для чтения данных можно заказывать и динамически, для чего следует воспользоваться такой функцией, как malloc. Если в операторе | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||


