48421 (608599), страница 2
Текст из файла (страница 2)
Как следует из его названия, первоначально HTTP предназначался для передачи между приложениями так называемого гипертекста (hypertext), представляющего собой особый вид данных, созданный в соответствии со стандартом HTML (HyperText Markup Language – язык разметки гипертекста). Гипертекстовый документ состоит из данных, размеченных с помощью тегов (tag) языка HTML, и представляет собой комбинацию текста, изображений, гиперссылок и прочих средств представления данных. Гиперссылки – одна из важнейших составляющих HTML-документа – представляют собой интерактивные области, воздействие на которые приводит к получению связанных с гиперссылкой данных. Это позволяет пользователю, работающему с гипертекстовой информацией, осуществлять навигацию в пределах набора документов или даже всей сети Интернет, получая интересующую его информацию с помощью контекстных гиперссылок.
Протокол HTTP является надстройкой над протоколом TCP и является средством контроля содержания передаваемых данных. В отличие от TCP, который не учитывал структуру передаваемых пакетов, HTTP внедряет в данные метаинформацию, позволяющую получателю корректно интерпретировать полученные данные. На основе HTTP функционирует глобальная сеть Интернет (называемая также World Wide Web или WWW). Первая версия протокола – HTTP/0.9 – обладала достаточно ограниченными возможностями, но с активным развитием всемирной сети появились новые версии: HTTP/1.0 и HTTP/1.1, позволяющие контролировать передачу по вычислительным сетям не только гипертекстовой информации, но и произвольные бинарные файлы: звуковые, графические, архивные и пр.
В силу того, что HTTP является надстройкой над протоколом TCP, при передачи данных также выделяются две стороны: клиент и сервер.
Клиент является инициатором соединения и запрашивает у сервера некоторые данные или услуги. Клиентом, как правило, является программа, называемая браузером (browser), позволяющая как отображать гипертекстовую информацию, так и принимать файлы иных форматов. Чтобы получить некоторую интересующую информацию, клиент посылает серверу запрос (request), содержащий описание запрашиваемой информации.
Сервер при передаче данных через HTTP называют веб-сервером (web-server). Эта программа осуществляет обработку запросов от клиентов, передавая запрошенные данные в виде ответов (response), содержащих помимо искомых данных метаинформацию, их описывающую.
Получение пользователем интересующих его данных состоит из следующих этапов:
-
Пользователь вводит в строке браузера адрес интересующего его ресурса.
-
Браузер на основе информации, полученной от пользователя, а также учитывая свои настройки и конфигурацию операционной системы, формирует запрос.
-
Браузер подключается к серверу, расположенном, возможно, на удаленном компьютере, и передает ему запрос.
-
Сервер, анализируя запрос, выполняет необходимые действия: формирует ответ, включая в него тело запрошенного документа. Если это гипертекстовый документ, он загружается из файла или же генерируется динамически посредством сценария. В ответ также включается информация о содержащихся в нем данных.
-
Сервер передает ответ браузеру.
-
Браузер анализирует ответ и либо сохраняет полученные данные в файл, либо, в случае гипертекстового документа, анализирует теги HTML и отображает документ на экране.
Следует заметить, что клиентской программой может быть не только браузер, тем не менее, все шаги, за исключением, может быть, первого, выполняются в любом случае.
Следует заметить, что здесь рассматривается непосредственное подключение клиента к серверу, содержащему интересующую информацию, однако, это не всегда возможно в силу различных обстоятельств. В таком случае подключение может осуществляться посредством одной или более промежуточных точек подключения. Можно разделить эти промежуточные точки на три группы:
-
Прокси-серверы (proxy-server) – программа-посредник, выполняющая функции как клиента, так и сервера с целью создания запросов от имени других клиентов. Запросы обслуживаются прокси-сервером, или пересылаются им с внесением в них изменений (в этом случае прокси-сервер называется непрозрачным) или без изменений (в этом случае прокси-сервер называется прозрачным). Прокси-сервер позволяет группе компьютеров выступать в качестве одного клиента, что часто применяется при подключении к Интернету локальных сетей.
-
Шлюз (gateway) – как и прокси-сервер, осуществляет трансляцию запросов, однако, не подвергаю их изменению. Шлюз получает от клиента запрос, как к серверу, содержащему искомый ресурс. Таким образом, клиент не может определить, подключается ли он через шлюз или непосредственно к содержащему ресурс серверу.
-
Туннель (tunnel) – программа-посредник, поддерживающая соединение. Хотя после установки соединения туннель не рассматривается в качестве элемента передачи через протокол HTTP, соединение, как правило, инициируется именно HTTP-запросом. Туннель прерывает свою работу, если хотя бы один из участников обмена данными закрывает соединение.
Для сохранения функциональности передачи данных при подключении через промежуточные точки не требуется внесения изменений в запросы и ответы, за исключением случая прокси-сервера: в этом случае в клиентском запросе должны содержаться дополнительные поля. Однако, с точки зрения сервера, обмен данными производится непосредственно с клиентом, следовательно, никаких изменений в запросах не происходит. Поэтом при разработке программы возможность подключения через промежуточные точки не учитывалась.
Запрос, отправляемый клиентом серверу, служит для точной идентификации запрашиваемого ресурса, а также содержит сведения, необходимые для корректной обработки запроса.
По своей структуре запрос состоит из трех частей:
-
Строка запроса
-
Блок заголовков
-
Объект
Строка запроса состоит из трех полей, разделенных символами пробела (ASCII-код 20h, далее SP), и заканчивается комбинацией из двух символов: возврат каретки (ASCII-код 0Dh, далее CR) и перевод строки (ASCII-код 0Ah, далее LF). Элементы строки запроса представлены следующими полями:
-
Метод (method) – определяет метод обработки, применяемый к запрашиваемому ресурсу. В зависимости от указанного метода формат запроса может быть различным. Допустимые методы:
-
OPTIONS
-
GET
-
HEAD
-
POST
-
PUT
-
DELETE
-
TRACE
-
При разработке программы была введена поддержка только метода GET, в силу того, что именно этот метод браузер указывает в запросе, создаваемом по умолчанию.
-
URI (Universal Resource Identifier) ресурса (resource URI) – указывает местоположение запрашиваемого ресурса в стандартизованном формате, то есть является адресом ресурса. При использовании метода GET данная строка может включать в себя набор параметров, передаваемых серверу в виде строк формата «имя_параметра = значение_параметра», разделенных символами амперсанда ‘&’. Блок параметров находится в конце строки URI и отделяется от адреса символом вопросительного знака ‘?’.
-
Версия протокола HTTP – при разработке программы была реализована поддержка приема запросов, соответствующих версиям 1.0 и 1.1, которым соответствуют строки «HTTP/1.0» и «HTTP/1.1» соответственно.
Блок заголовков, следующий за строкой запроса, может состоять из одного или более заголовков:
-
Заголовок запроса – содержит поля, служащие модификаторами запроса и содержащие информацию о запросе и о конфигурации клиентской машины.
-
Заголовок объекта – в случае, если запрос включает в себя некоторый объект (произвольный набор данных), поля этого заголовка описывают объект, указывая его формат, кодировку и другие параметры.
-
Общий заголовок – содержит служебные параметры, необходимые для обеспечения корректности передачи и включения дополнительных услуг, таких, как кэширование.
Раздел заголовков оканчивается двумя парами символов CR и LF, что позволяет легко определить факт окончания приема запроса в силу того, что сам запрос подобную комбинацию символов содержать не может.
Ответ, отправляемый сервером клиенту, может быть создан только в результате обработки клиентского запроса. Он содержит описание результатов выполнения запроса и, если были запрошены данные, включает в себя запрошенный ресурс.
По своей структуре ответ состоит из следующих частей:
-
Строка состояния
-
Блок заголовков
-
Объект
Строка состояния состоит из трех полей, разделенных символами SP, и содержит в конце последовательность символов CR, LF. Элементы строки состояния:
-
Версия протокола HTTP – разработанная программа всегда использует строку «HTTP/1.1».
-
Код состояния (status code) – трехсимвольный цифровой код, который идентифицирует результат выполнения запроса. Хотя стандартом определен достаточно большой набор кодов состояния, в программе используются следующие коды:
-
200 – успешное выполнение;
-
400 – некорректный запрос;
-
401 – несанкционированный доступ;
-
404 – ресурс не найден;
-
405 – неприменимый метод;
-
505 – неподдерживаемая версия HTTP.
-
Фраза состояния (reason phrase) – короткая фраза, поясняющая код состояния выполнения запроса. Стандартом предложен стандартный набор фраз, однако в программе этот набор был несколько модифицирован.
Блок заголовков, следующий за строкой состояния, может состоять из одного или более заголовков:
-
Заголовок запроса
-
Заголовок объекта
-
Общий заголовок
Подробное рассмотрение заголовков было произведено в п. 2.2.3.3.
Раздел заголовков оканчивается двумя парами символов CR и LF, после чего следует произвольный набор символов – объект. При работе программы такими объектами могут являться только гипертекстовые документы в формате HTML, динамически генерируемые подключаемыми модулями.
1.3 Системная информация ОС Linux
1.3.1 Расположение системной информации
Всю системную информацию об операционной системе Linux можно разделить на две группы – по признаку расположения этой информации в системе:
-
Статическая информация – к этой группе можно отнести все текстовые конфигурационные файлы, оказывающие влияние на процесс загрузки системы, функционирование ее компонент. Подобная информация, как правило, расположена в каталоге /etc и его подкаталогах.
-
Динамическая информация – описывает текущее состояние системы. Подобная информация может быть получена чтением контекста памяти ядра операционной системы; доступ к этой информации осуществляется через файловую систему /proc (см. п. 2.3.2).
Методы получения информации можно также разделить на несколько групп по способу организации взаимодействия с системой:
-
Чтение файлов конфигурации и файлов, расположенных в /proc, с помощью системных вызовов.
-
Вызов системных утилит, предоставляющих соответствующую информацию.
-
Получение информации посредством выполнения специальных системных вызовов.
1.3.2 Файловая система /proc
Как было указано в п. 2.3.1, для получения динамической информации о системе необходимо получить доступ к контексту памяти ядра. В операционной системе Linux память ядра отображается на устройство /dev/kmem. Однако, чтение непосредственно из этого устройства может представлять достаточно большую сложность в силу того, что возникает необходимость знать расположение структур данных в памяти ядра. В ранних версиях UNIX-систем доступ к информации осуществлялся именно так.
Впоследствии был предложен механизм доступа к структурам памяти ядра, который существенно облегчал получение системной информации: большинство структур данных были отображены в файлы и каталоги, составляющие иерархию, фактически существующую в структурах данных ядра. Все эти файлы и каталоги были объединены в специальную файловую систему - /proc.
Адреса структур данных ядра заносятся в /proc на этапе компиляции системы. Соответственно, программы, обращающиеся к /proc, должны учитывать возможность ее модификации при установке более новой версии ядра с, возможно, измененной структурой /proc.
Обращение к файловой системе /proc происходит тем же путем, что и к обычной дисковой файловой системе – с помощью системных вызовов read() и write(). Следует, однако, заметить, что /proc не связана с каким-либо физическим устройством: содержимое файлов /proc генерируется непосредственно при чтении этих файлов, что приводит к невозможности определить их размер обычными средствами, а попытка узнать время создания и модификации любого файла приведет к получению текущего времени.
Некоторые файлы системы /proc могут быть использованы и для записи в них данных для изменения состояния системы, однако эта возможность не предусматривалась при разработке программы.
Файловая система /proc содержит по одному каталогу для каждого выполняющегося в данный момент процесса. Именем каталога является идентификатор процесса; в некоторых UNIX-системах идентификатор дополняется нулями для придания именам каталогов процессов одинаковой длины, однако, в ОС Linux подобные действия не производятся.
Каталоги процессов динамически создаются и уничтожаются по мере запуска и завершения соответствующих процессов. В каждом каталоге имеются файлы, предоставляющие доступ к различной информации о процессе.
Каждый каталог процесса содержит следующие файлы:
-
cmdline – содержит список аргументов, переданный процессу при запуске; первым аргументом является имя исполняемого файла; в случае, если процесс выгружен (например, находится в состоянии зомби), файл будет пуст;
-
cwd – является символической ссылкой на текущий рабочий каталог процесса;
-
environ – содержит переменные среды процесса;
-
exe – является символической ссылкой на исполняемый файл процесса; ее чтение является практически единственным способом определить каталог, содержащий исполняемый файл;
-
fd – подкаталог, содержащий символические ссылки на файлы, открытые процессом;
-
maps – содержит информацию о файлах, отображаемых в адресном пространстве процесса; к числу отображаемых файлов относится исполняемый файл процесса, а также загруженные библиотеки;
-
root – является символической ссылкой на корневой каталог процесса;
-
stat – содержит статистическую информацию о процессе;
-
status – содержит те же данные, что и stat, но в отформатированном виде.
Из соображений безопасности права доступа к некоторым файлам каталогов процесса предоставлены только владельцу процесса или суперпользователю.
В файловой системе /proc есть дополнительный элемент, позволяющий программам находить информацию о своем собственном процессе. Файл /proc/self является символической ссылкой на каталог, соответствующий текущему процессу. Разумеется, содержимое ссылки зависит от того, какой процесс к ней обращается.
Информация об аппаратуре, установленной на компьютере, может быть получена из следующих файлов файловой системы /proc:
-
/proc/cpuinfo – содержит информацию о центральном процессоре (или процессорах, если их больше одного); файл содержит информацию в отформатированном виде; помимо указания модели процессора, файл содержит указание доступных процессорных функций, таких как расширенные инструкции MMX;
-
/proc/devices – содержит список старших номеров всех символьных и блочных устройств, установленных в системе;
-
/proc/pci – содержит информацию обо всех устройствах, подключенных к шине PCI, включая устройства, встроенные в материнскую плату;
-
/proc/ide – каталог, содержащий файлы, которые описывают устройства, подключенные к шинам IDE и SCSI.
-
/proc/net/dev – содержит информацию о сетевых платах и их конфигурации.
Информация о конфигурации и состоянии ядра системы представлена в следующих файлах:
-
/proc/version – содержит строку, описывающую номер версии и модификации ядра; в нее также включена дополнительная информация: имя пользователя, осуществившего компиляцию, дата компиляции и версия компилятора;
-
/proc/meminfo – хранит сведения об использовании системной памяти; указываются данные как о физической памяти, так и об области подкачки;
-
/proc/modules – полный список установленных модулей ядра в текстовом виде.
Информация о файловых системах представлена следующими файлами:
-
/proc/filesystems – список файловых систем, поддерживаемых ядром;
-
/proc/mounts – содержит перечень смонтированных файловых систем; каждая строка файла содержит имя устройства, имя точки монтирования, тип файловой системы и флаги монтирования.
2. Технологический раздел
2.1 Выбор языка программирования
В настоящее время в UNIX-подобных операционных системах представлено большое количество самых разнообразных языков программирования, каждый из которых обладает своими преимуществами. При разработке программы был выбран язык C и соответствующий ему компилятор из пакета gcc (GNU compilers collection) по следующим причинам:
-
В силу того, что само ядро операционной системы написано на языке C, компилятор языка, входящий в состав пакета gcc, постоянно обновляется и исправляется, что практически исключает ошибки при компиляции с его стороны; в свою очередь, это приводит к генерации наиболее оптимизированного кода;
-
Язык C предполагает использование простых конструкций, что выгодно отличает его от остальных языков, особенно интерпретируемых и объектно-ориентированных, с точки зрения скорости выполнения программ;
-
Язык C предоставляет программисту наиболее полный доступ ко всем возможностям программного интерфейса POSIX, что позволяет наиболее эффективно организовывать взаимодействие программы с операционной системой.
2.2. Программные средства
2.2.1 Потоки
Разработанная программа имеет возможность параллельной обработки запросов от нескольких клиентов. Это достигнуто за счет использования более чем одного потока управления, осуществляющих обработку запросов.