Порт Apache для EBCDIC
Обзор порта Apache для EBCDIC
Версия 1.3 Apache HTTP Server стала первой версией, включавшей порт для мейнфрейма, отличного от ASCII, использующего набор символов EBCDIC в качестве собственного набора кодов.
(Это семейство мейнфреймов SIEMENS, на которых работает операционная система BS2000/OSD. В настоящее время эта ОС мейнфрейма включает POSIX-подсистему на основе SVR4).
Изначально порт был создан, чтобы
- доказать возможность переноса HTTP-сервера Apache на эту платформу
- найти «достойную и надёжную» замену почтенному демону CERN-3.0 (который был перенесён несколько лет назад), а также
- доказать, что модель процессов Apache с предварительным созданием дочерних процессов на этой платформе может легко превзойти по производительности модель accept-fork-serve, используемую CERN, в 5 и более раз.
Этот документ описывает обоснование некоторых проектных решений, принятых при создании порта для этой машины.
Цели разработки
Одной из целей порта EBCDIC было сохранить достаточную обратную совместимость с сервером CERN для EBCDIC, чтобы переход на новый сервер был привлекательным и простым. Для этого потребовалось добавить настраиваемый способ определения того, хранится ли HTML-документ в ASCII (единственный формат, принимаемый старым сервером) или в EBCDIC (родной формат документов в POSIX-подсистеме и, следовательно, единственный реалистичный формат, с которым могли работать другие POSIX-инструменты, например grep или sed). Текущее решение этой задачи — «псевдоформат MIME», который перехватывается и интерпретируется сервером Apache (см. ниже). В будущих версиях эта проблема может быть решена путём определения «обработчика ebcdic» для всех документов, требующих преобразования.
Техническое решение
Поскольку весь ввод и вывод Apache основан на типе данных BUFF и его методах, самым простым решением было добавить преобразование в процедуры обработки BUFF. Преобразование должно включаться и выключаться в любой момент, поэтому был добавлен флаг BUFF, определяющий, включено ли преобразование для объекта BUFF в данный момент. Этот флаг изменяется в нескольких местах протокола HTTP:
- включается перед получением запроса (поскольку запрос и строки заголовка запроса всегда представлены в формате ASCII)
- включается/выключается при получении тела запроса — в зависимости от типа содержимого тела запроса (поскольку тело запроса может содержать текст ASCII или двоичный файл)
- включается перед отправкой заголовка ответа (поскольку строки заголовка ответа всегда представлены в формате ASCII)
- включается/выключается при отправке тела ответа — в зависимости от типа содержимого тела ответа (поскольку тело ответа может содержать текст или двоичный файл)
Примечания по переносу
-
Соответствующие изменения в исходном коде разделены с помощью
#ifdefна две категории:#ifdef CHARSET_EBCDIC-
Код, необходимый для любой машины на основе EBCDIC. Сюда входят преобразования символов, различия в непрерывности двух наборов символов, флаги, указывающие, какую часть протокола HTTP нужно преобразовать, а какую нет, и т. д.
#ifdef _OSD_POSIX-
Код, необходимый только для платформы мейнфреймов SIEMENS BS2000/OSD. Он учитывает различия в подключаемых заголовочных файлах и особенности реализации сокетов, необходимые только на платформе BS2000/OSD.
-
Возможность преобразования ASCII и EBCDIC на уровне сокетов (в BS2000 POSIX есть параметр сокета, поддерживающий это) намеренно не использовалась, поскольку поток байтов на уровне протокола HTTP состоит из смеси строк протокола и необработанных данных файлов, не относящихся к протоколу. Строки протокола HTTP всегда кодируются в ASCII (запрос
GET, любые строки заголовков, информация о разбиении на блоки и т. д.), тогда как части передачи файлов (т. е. изображения GIF, вывод CGI и т. д.) обычно должны просто передаваться сервером «как есть». Это разделение на «строку протокола» и «необработанные данные» отражено в коде сервера функциями вродеbgets()илиrvputs()для строк и функциями вродеbwrite()для двоичных данных. Поэтому глобальное преобразование всего содержимого было бы неподходящим решением.(Разумеется, для текстовых файлов необходимо предусмотреть, чтобы документы EBCDIC всегда передавались в ASCII.)
-
Поэтому в этом порте реализовано встроенное преобразование на уровне протокола для внутренних строк сервера (которые компилятор преобразовал в строки EBCDIC), а значит, и для всех документов, создаваемых сервером. Исключение составляют жёстко заданные ASCII-последовательности
\012и\015, повсеместно используемые в коде сервера: они уже являются двоичным представлением ASCII-символов\nи\rи не должны повторно преобразовываться в ASCII. Это исключение относится только к строкам, создаваемым сервером; от внешних документов EBCDIC не ожидается наличия символов новой строки ASCII. -
Изучив иерархию вызовов процедур управления BUFF, я добавил «слой преобразования ebcdic/ascii», через который проходят все операции puts/write/get/gets, а также флаг преобразования, позволяющий включать и отключать преобразования на лету. Обычно документ проходит через этот слой дважды на пути от источника (файла или вывода CGI) к месту назначения (запрашивающему клиенту):
file -> ApacheиApache -> client.Теперь сервер может прочитать строки заголовка вывода CGI-скрипта в формате EBCDIC, а затем определить, что оставшаяся часть вывода скрипта представлена в ASCII (как в случае вывода программы-счётчика WWW: тело документа содержит изображение GIF). Вся обработка заголовков выполняется в родном формате EBCDIC; затем сервер, исходя из типа передаваемого документа, определяет, представлено ли тело документа (за исключением информации о разбиении на блоки, разумеется) уже в ASCII или его необходимо преобразовать из EBCDIC.
-
Для текстовых документов (типы MIME text/plain, text/html и т. д.) можно использовать неявное преобразование в ASCII. Также их можно передавать без преобразования, если пользователи предпочитают хранить некоторые документы в необработанном формате ASCII для ускорения передачи или если файлы находятся в дереве каталогов, смонтированном через NFS.
Пример:
Чтобы передавать файлы с суффиксом
.ahtmlкак документыtext/htmlв необработанном формате ASCII без неявного преобразования (а файлы с суффиксом.ascii— какtext/plainв формате ASCII), используйте директивы:AddType text/x-ascii-html .ahtml AddType text/x-ascii-plain .ascii
Аналогично, любой тип MIME
text/fooможно передавать как «необработанный ASCII», настроив для него тип MIME «text/x-ascii-foo» с помощьюAddType. -
Нетекстовые документы всегда передаются в двоичном режиме, без преобразования. Это представляется наиболее разумным вариантом, например, для файлов GIF/ZIP/AU. Разумеется, для этого пользователю необходимо копировать их на хост мейнфрейма с помощью двоичного переключателя «
rcp -b». -
Предполагается, что файлы, обрабатываемые сервером, всегда хранятся в родном для машины формате (т. е. EBCDIC) и преобразуются после обработки.
-
Для вывода CGI необходимость преобразования определяется CGI-скриптом: если указать подходящий Content-Type, текстовые файлы можно преобразовать, а вывод GIF передать без изменений. Примером последнего случая служит программа wwwcount, которую мы также перенесли.
Примечания по хранению документов
Двоичные файлы
Все файлы, у которых Content-Type: не начинается с text/, сервер считает двоичными файлами и не преобразует. Примерами двоичных файлов являются изображения GIF, файлы, сжатые с помощью gzip, и подобные им.
При обмене двоичными файлами между хостом мейнфрейма и компьютером Unix или Windows обязательно используйте команду ftp «binary» (TYPE I) или команду rcp -b на хосте мейнфрейма (переключатель -b не поддерживается в вариантах unix rcp).
Текстовые документы
По умолчанию сервер предполагает, что текстовые файлы (т. е. все файлы, у которых Content-Type: начинается с text/) хранятся в родном для хоста наборе символов — EBCDIC.
Документы с включениями на стороне сервера
В настоящее время документы SSI должны храниться только в формате EBCDIC. Преобразование из ASCII перед обработкой не предусмотрено.
Состояние модулей Apache
| Модуль | Состояние | Примечания |
|---|---|---|
core | + | |
mod_access | + | |
mod_actions | + | |
mod_alias | + | |
mod_asis | + | |
mod_auth | + | |
mod_authn_anon | + | |
mod_authn_dbm | ? | с собственным libdb.a
|
mod_authz_dbm | ? | с собственным libdb.a
|
mod_autoindex | + | |
mod_cern_meta | ? | |
mod_cgi | + | |
mod_digest | + | |
mod_dir | + | |
mod_so | - | нет общих библиотек |
mod_env | + | |
mod_example | - | (только тестовая среда) |
mod_expires | + | |
mod_headers | + | |
mod_imagemap | + | |
mod_include | + | |
mod_info | + | |
mod_log_agent | + | |
mod_log_config | + | |
mod_log_referer | + | |
mod_mime | + | |
mod_mime_magic | ? | пока не перенесён |
mod_negotiation | + | |
mod_proxy | + | |
mod_rewrite | + | не проверен |
mod_setenvif | + | |
mod_speling | + | |
mod_status | + | |
mod_unique_id | + | |
mod_userdir | + | |
mod_usertrack | ? | не проверен |
Состояние сторонних модулей
| Модуль | Состояние | Примечания |
|---|---|---|
JK (Formerly mod_jserv) | - | Перенос JAVA всё ещё продолжается. |
mod_php3 | + |
mod_php3 работает без проблем с библиотеками LDAP, GD и FreeType. |
mod_put | ? | не проверен |
mod_session | - | не проверен |
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/platform/ebcdic.html