В этом документе приведены примеры наиболее
распространенных конфигураций, применяемых на практике. По-хорошему, он не
очень нужен т.к. все тонкости упомянуты в
описании директив конфигурации и
описании принципов работы сервера. Однако
наличие готовых примеров сильно уменьшает поток писем с просьбой о помощи.
В конце документа приведено описание переменных окружения,
которые могут быть использованы в CGI-скриптах и Russian Apache API -
функций и макросов, которые могут быть использованы при написании собственных
модулей. Для модулей на Perl предусмотрен Russian Apache Perl API.
Этот документ переработан с учетом новых директив конфигурации и нового
поведения сервера, появившихся в версиях PL18-PL28,
пользователи старых (PL12-PL16) версий могут использовать
старую версию этого документа, хотя она и
несколько невнятная.
Общая идея всех приводимых ниже примеров конфигурации
совершенно одинакова:
Имеется "основной" сервер (www.company.ru), который
автоматически распознает кодировку клиента по Accept-Charset и User-Agent.
В большинстве случаев он будет правильно распознавать кодировку клиента,
но получаемые таким образом
документы не могут быть кэшированы (т.к. одному URL соответствует различный
content в различных ситуациях), что осложняет работу по медленным каналам.
Для каждого документа основного сервера имеется некоторое количество (по
числу поддерживаемых кодировок) "виртуальных URL".
Содержимое
этих URL одинаковое, а кодировка не зависит от User-Agent (но зависит от
Accept-Charset).
Возможны несколько вариантов создания таких "виртуальных URL" -
виртуальные директории,
виртуальные сервера с разными hostname (см. также
пример упрощенной конфигурации для Apache-1.3) и
виртуальные сервера, разнесенные по номерам портов.
Каждый способ имеет свои недостатки и преимущества, выбор нужного метода
остается целиком на совести администратора. Во всех трех случаях, документ
полученный с URL с "явным выбором кодировки" может быть кэширован
как HTTP/1.0, так и HTTP/1.1-совместимыми кэшами (т.е. заголовок Expires:
не ставится, а в заголовке Vary: остается только accept-charset).
Начиная с Apache-1.3.1 RUS PL26, можно использовать внешние модули определяющие
кодировку клиента по каким-либо параметрам и передающие название требуемой
кодировки в mod_charset через переменную окружения. См.
пример использования этой возможности совместно с RewriteModule.
Пример конфигурации основного сервера имеется в комплекте
"Russian Apache", далее в этом документе мы рассмотрим только
изменения и дополнения, которые нужно сделать в конфигурации в том или ином
случае.
Основное достоинство этого метода заключается в его простоте, а основной
недостаток состоит в том, что все ссылки между документами должны быть с
относительным путем.
Т.е. вместо <A HREF="/some">, нужно писать что-то вроде
<A HREF="../../../some"> по той причине, что при переходе из
документа /koi8-r/file.html на ссылку /some произойдет переключение на
автоматическую перекодировку (для сохранения явного выбора кодировки
переходить нужно на /koi8-r/some т.е. на ../some).
Необходимая строгость совпадения имени кодировки и имени директории
задается директивой
CharsetStrictURIMatch.
Существуют как минимум два способа настройки сервера для работы в таком
режиме:
Если первые символы (либо host part - см директиву
CharsetStrictURIMatch
hostname совпадают с названием (или alias)
какого-либо charset, то (при настройке
CharsetSelectionOrder
по умолчанию) сервером будет выбран именно этот charset. Пример
конфигурации:
<VirtualHost win-www.domain.ru>
# вообще-говоря, никаких дополнительных директив не нужно
</VirtualHost>
В-принципе, имя виртуального хоста может быть совершенно произвольным.
В этом случае можно использовать такую конфигурацию:
<VirtualHost any.domain.ru>
CharsetSelectionOrder
CharsetDefault windows-1251 # например
</VirtualHost>
В этом примере использована пустая директива
CharsetSelectionOrderт.е.
все способы автоматического определения кодировки (Portnumber, Hostname,
Dirprefix, Useragent) выключены и документ отдается в default-кодировке.
Но в случае, если
клиентская программа включила в запрос заголовок Accept-Charset и требуемый
charset известен серверу, то будет удовлетворено требование клиента. Всякое
другое поведение противоречит стандартам HTTP.
Виртуальные сервера и DNS
Если вы ожидаете, что на ваш сервер будут ходить HTTP/1.0-совместимые
клиенты, то каждый виртуальный сервер должен иметь свой IP-адрес. Протокол
HTTP/1.1 может обходиться без отдельных IP-адресов т.к. в каждом запросе
должен присутствовать обязательный заголовок Host:, сообщающий серверу к
какому именно серверу обращается клиент. Заголовок Host ставят и
некоторые HTTP/1.0 клиенты, но это не является обязательным их свойством.
Как следствие, для использования механизма виртуальных серверов, DNS-зона
для домена должна содержать записи типа A, а обратная
(address->hostname) зона - корректные записи типа PTR. Корректная
обратная зона необходима Apache-1.2.x
для правильной обработки HTTP/1.0 (без Host:) запросов. Версии 1.1.x были
менее требовательны к этому.
При этом, Apache-1.2.x (как с правками, так и без) делает все обращения к
DNS в момент startup (или переконфигурации), поэтому записи в DNS должны
быть корректными на момент старта сервера (я бы не писал про
это так много, но это - достаточно распространенные проблемы).
Более подробно об особенностях работы Apache с виртуальными серверами можно
прочитать прямо на
WWW-сервере проекта Apache.
В Apache 1.3 появилась очень хорошая возможность указать виртуальному серверу принимать
все запросы, hostname которых подпадает под определенную маску. Делается это командой
ServerAlias *.www.youcompany.com. Начиная с Russian Apache Pl26.0,
в директиве CharsetSelectionOrder можно
задать параметр URIHostname, который включает возможность сравнения имени
hostname к которому был реальный запрос с именем какого-либо charset (правило
Hostname сравнивает с именем сервера, написанным в директиве <VirtualHost>)
Пример:
При обращениях к windows-1251.www.foo.net и к koi8-r.www.foo.net клиенту будет
отдана соответствующая кодировка. Естественно, оба хоста должны иметь
соответствующие записи в DNS (достаточно CNAME).
Достоинства и недостатки схемы с <VirtualHost>
Достоинства очевидны - все ссылки (<A HREF=) в документе могут быть
абсолютными. Недостатки тоже очевидны - пока существуют HTTP/1.0-совместимые
клиенты, не ставящие заголовок Host:, для каждого виртуального сервера
необходим свой IP-адрес и корректная настройка зон в DNS (т.е. нужен или
доступ к DNS или доступ к понимающему проблему администратору). Это не
является большой проблемой для "официального webmaster'а", но
может являться проблемой для администраторов персональных серверов.
При этом способе явного задания кодировки, соответствующие URL будут такими:
http://www.domain/file.html - автоматический выбор кодировки
http://www.domain:port/file.html
(например - http://www.domain:8001/file.html) - кодировка задается номером
порта в URL (это делается директивой CharsetByPort
и/или явной настройкой <VirtualHost>.
Для того, чтобы сервер "слушал" (listen(2)) более чем на одном
TCP-порту, необходимо использовать директиву Listen Portnumber,
например так:
Listen 80
Listen 8100
Listen 8101
# и так далее
Директива Listen 80 необходима т.к. наличие директивы Listen
выключает директиву Port (точнее, при наличии Listen, Port отвечает
только за содержимое CGI-переменной SERVER_PORT).
Для того, чтобы связать какую-то определенную кодировку с номером порта,
существует по меньшей мере 2 способа:
При такой конфигурации кодировка будет выбираться по номеру порта для
всех виртуальных серверов.
Кодировку можно задать прямо в описании виртуального сервера:
Listen 80
Listen 8100
Listen 8101
<VirtualHost some.domain:8100>
CharsetDefault koi8-r
CharsetSelectionOrder # опять пустая директива, см. выше
</VirtualHost>
В обоих случаях для каждой пары hostname:port можно переопределить
поведение; более того, все директивы могут встречаться и в файлах
.htaccess т.е. возможности
для создания запутанной структуры сервера просто безграничны.
Некоторые особенности работы с перекодировкой по портам
При обращении "к директории" с пропущенным trailing slash в
URL (например http://www.server.ru/directory), mod_dir из
apache_1.2.x
делает Redirect на http://www.server.ru/directory/. Все было бы
хорошо, но в случае недостаточно полно сконфигурированного сервера, код из
mod_dir не ставит правильный номер порта. Так при обращении к
http://www.server.ru:8000/directory клиенту будет выдан редирект
на http://www.server.ru/directory/, что неприемлемо.
"Лечение"
этой особенности возможно несколькими способами:
Apache_1.2.4 RUS PL21.1 и выше содержит правки к mod_dir, в
результате номер порта всегда подставляется правильный.
Если виртуальные хосты не используются, то нужно убрать из
конфигурационных файлов Apache все директивы Port и сервер будет
работать корректно.
При использовании виртуальных хостов и перекодировки по портам
необходимо описать директивой <VirtualHost> каждую
используемую пару Host:port. Как-то так:
<VirtualHost host1:80>
# тут можно ничего не писать, хотя для настоящих VirtualHost придется
# продублировать по меньшей мере директивы DocumentRoot
</VirtualHost>
<VirtualHost host1:8100>
...
</VirtualHost>
<VirtualHost host2:80>
...
</VirtualHost>
<VirtualHost host2:8100>
...
</VirtualHost>
Наверное, первый из перечисленных способов - самый простой.
Директивы класса
Redirect
(Redirect, RedirectTemp, RedirectPermanent) требуют задания последним
параметром полного URL на который нужно делать редирект. Понятно,
что при использовании перекодировки по номеру порта использование
Redirect* неудобно или невозможно. Вместо этих директив
предлагается использовать директиву
CharsetSoftRedirect
последний аргумент которой - URL относительно ServerRoot т.е.
hostname сервера и порт будут подставлены на runtime и будут правильными
Достоинства схемы:
Все ссылки в пределах сервера могут быть абсолютными.
Не расходуются дефицитные IP-адреса.
Недостатки:
При работе через фильтрующий firewall (packet filter) необходимо
открывать большее число портов чем обычно. Это может стать проблемой в
случае, когда администратор WWW и администратор firewall - разные
люди.
Так как "по сложившейся традиции" для WWW-серверов с явной
перекодировкой по номеру порта используются порты с номером больше 1024
(чаще всего - 8000-800x, 8080-8080x и так далее), а такие порты на UNIX
может открывать и непривилегированный пользователь, то возможны
некоторые проблемы с security. Т.е. потенциальный "взломщик"
может дождаться момента, когда основной сервер не запущен и запустить
свой fake сервер на тех же портах. Это не является сколько-нибудь
серьезной проблемой, но забывать об этом не следует
(workaround - выбирать порты с номером меньшим 1024).
Использование выбора кодировки по портам вместе с директивой
<VirtualHost>
Как выясняется, у администраторов WWW-серверов, желающих использовать такую
схему работы, когда
кодировка клиента задается по номеру порта;
директива <VirtualHost> используется для своей первоначальной цели -
размещения нескольких виртуальных серверов на одной машине,
часто возникает одна и та же проблема - при обращении к default-порту все
абсолютно нормально, а при обращении к любому другому - показывается содержимое
основного сервера (правда в желаемой кодировке).
Это поведение не является свойством "Russian Apache", а является
"feature" Apache-1.2.x и описано в документации к оригинальному
Apache. Для того, чтобы добиться желаемого поведения, директиву
<VirtualHost> нужно использовать в виде
<VirtualHost www.some.domain:*>
т.к. по умолчанию директива <VirtualHost> "имеет отношение"
только к порту, заданному директивой Port. Смотри также замечания
выше.
Внимание. Apache-1.2.0...1.2.5 содержит ошибку при работе с
"Host: -based" virtual hosts (т.е. работающими на одном
IP-адресе), которая приводит к тому, что конструкции <VirtualHost
host.domain> и <VirtualHost host.domain:*>
эквивалентны т.е. <VirtualHost> не работает на портах иных, чем
заданный директивой Port. Это явная ошибка, ее описание и патч уже
отосланы Apache-Team, но пока это не починено в оригинальной версии можно
пользоватьсяRussian Apache PL20.5 (или новее), где эта ошибка исправлена.
Эта ошибка исправлена и в Apache-1.2.6.
Начиная с версии PL26.0, Russian Apache может взаимодействовать с другими модулями
определения кодировки клиента. При этом mod_charset будет заниматься только перекодировкой.
Для этого "другие модули" должны установить переменную окружения FORCE_CHARSET
в значение, равное имени одного из charset, известных Russian Apache (для Apache-hackers -
переменная выбирается из таблицы r->subprocess_env). Это может делать любой модуль,
он должен сработать раньше, чем mod_charset.
В поставке оригинального Apache-1.3 есть три модуля, которые могут устанавливать
переменные окружения - mod_env, mod_setenvif и mod_rewrite. Первый из них неинтересен -
он ставит заданные переменные всегда. Два других позволяют добиться функциональности,
которой нет в mod_charset. Примеры:
Например, мы хотим отдавать документы пользователю, пришедшему по ссылке с www.foo.com
в кодировке koi8-r. Это делается директивой SetEnvIf модуля
mod_setenvif:
Допустим, все URL вида /windoze/some/file.html должны быть отданы в кодировке
windows-1251 и с "откушенным" префиксом /windoze. Конечно, это может быть
сделано через набор директив <Location> и Alias, но гораздо красивее
выглядит решение при помощи
mod_rewrite:
RewriteEngine On
RewriteRule /windoze/(.*) /$1 [E=FORCE_CHARSET:windows-1251]
Внимание. Момент "срабатывания" этого механизма зависит от
директивы CharsetSelectionOrder.
По-умолчанию, имя сервера и номер порта имеют больший приоритет, чем переменная
окружения.
Какой способ выбрать ?
На мой взгляд, перекодировка "по префиксу
директории" наиболее удобна для небольших (по содержанию)
серверов - таких, где за содержимым следят один-два
человека (в этом случае легко соблюсти требование относительности ссылок).
Перекодировка "по имени виртуального сервера" удобна в случае,
когда ведется на самом деле один (по содержанию) сервер.
Перекодировка "по номеру
порта" будет удобной, когда на одном компьютере сосуществуют несколько
разных по содержанию серверов. В этом случае выбор содержания будет
производиться
по имени виртуального сервера, а требуемая перекодировка - по номеру порта.
Прочие замечания
Language negotiation
В старой версии этого документа
рекомендовалось
использовать имеющийся в Apache механизм Language-negotiation. Эта
рекомендация остается верной и сейчас - при настройках по-умолчанию
сервер выдает строчку charset=... в заголовке Content-Type только если
язык документа (описываемый директивой AddLanguage) совпадает с
языком, описанным для данного charset директивой
CharsetDecl
(если быть точным, то дистрибутивный конфигурационный файл предлагает
по-умолчанию ровно обратное поведение - выдачу charset= для всех
документов).
Для изменения этого поведения можно использовать директиву
CharsetMatchLanguage.
В то же время, существуют некоторые проблемы, возникающие при использовании
механизма language negotiation, о которых необходимо упомянуть:
Если при обращении к документу /some/file.html у вас такого документа
нет, а есть документ /some/file.html.ru, то сервер скажет (на чистом
английском), что документа на запрошенном языке нет, но есть документ
с language=ru. Это совершенно верное с точки зрения стандартов
поведение, но не следует ожидать, что все пользователи Netscape
Communicator кинутся его перенастраивать на
Accept-Language: ru, хотя такая возможность в этой программе
имеется.
Директива ScriptAlias в Apache-1.2 несовместима с механизмом
Language negotiation и Option MultiViews с ней не работает.
Для этой директивы есть простая замена. Вместо
Документы, имеющие только Language-specific extension (например,
README.ru) не являются предметом Language Negotiation (т.е. запрос
вида GET /README с языком ru не будет удовлетворен). Аналогичная
проблема имеется с документами, для которых не описан Content-Type
(т.е. расширения которых не упоминаются в файле mime.types и в
директивах AddType).
Content-type и CGI-скрипты
Сервер сам ставит строку charset=CHARSET_NAME в
окончательную выдачу документа клиенту. Поэтому об этом не нужно
беспокоиться.
Русские имена файлов
Вообще, использование русских имен файлов - потенциальный источник всяких
странностей. Есть ряд причин, по которым эти имена трудно обрабатывать в
Russian Apache, останавливаться на которых я сейчас не буду.
После некоторого обсуждения,
общество
решило, что простейшим решением будет вовсе не перекодировать имена файлов
при обработке запроса. Т.к. в старых версиях поведение по-умолчанию было
иным (имена файлов перекодировались, но слишком поздно), то пришлось
сделать для этого специальную директиву CharsetRecodeFilenames.
Таким образом, чтобы создавать файлы с русскими именами вам необходимо:
Выключить перекодировку имен файлов директивой
CharsetRecodeFilenames Off
Все буквы не из US-ASCII кодировать в именах этих файлов как %aa
(т.е. вместо файл.html писать %c6%c1%ca%cc.html)
Если вы используете CGI с русскими именами, то правильное имя скрипта
будет лежать в переменной $SCRIPT_NAME, а $REQUEST_URI будет
перекодирован целиком. Т.е. чтобы сделать
"ссылку на самого себя" нужно писать
${SCRIPT_NAME}?${QUERY_STRING}, а не ${REQUEST_URI}
А вообще, русские имена файлов создают больше проблем, чем решают.
Переменные окружения
Russian Apache добавляет переменные окружения, которые доступны
из CGI-скриптов и модулей. Полный список таков:
CHARSET - официальное название кодировки клиента, заданное директивой
CharsetDecl
SOURCE_CHARSET - кодировка документа (скрипта) - та кодировка, в которой
сервер ожидает получить документ перед отправкой его клиенту.
CHARSET_SERVER_NAME - имя сервера в формате www.domain:port -
переменная добавлена т.к. стандартная переменная HTTP_HOST не всегда
корректно работает (она повторяет то, что клиент передал в заголовке Host:).
CHARSET_SERVER_PORT - реальный (используемый в данный момент) номер
порта (значение стандартного HTTP_PORT совпадает со значением директивы
Port в конфигурации сервера).
CHARSET_SERVER_METHOD - http:// или https://
Использование последних трех переменных позволяет, например, делать
корректные редиректы из скрипта.
Russian Apache API
При разработке собственных модулей бывает необходимо использовать функциональность,
уже существующую в Russian Apache - например перекодировать какую-то строку из
кодировки сервера в кодировку клиента. Естественно, можно использовать все не-static
функции из mod_charset, но для некоторых из них гарантировано, что их интерфейс не
будет меняться (по мере сил, естественно :)
Russian Apache API включен в Russian Apache PL27.0 и выше.
Russian Apache API включает в себя такие макросы, вызовы и т.п.:
Заголовочный файл - mod_charset.h. Расположен в src/modules/extra/mod_charset.h.
Defines:
RUSSIAN_APACHE - определена, если сервер собирается вместе с mod_charset.
MOD_CHARSET_MAGIC - определяет версию API. Текущая (она же - первая) версия
имеет номер 19981025. Подразумевается, что более новые версии Russian Apache API
включают в себя старые версии без изменений.
Вызовы функций:
Все вызовы функций получают в качестве первого параметра текущий запрос
(request_rec* r). Все они могут вызываться только после стадии
обработки fixup т.е. в момент выдачи ответа клиенту в противном случае они
возвращают 0 или NULL (в зависимости от типа возвращаемого значения) и никаких
других действий не производят.
Список функций:
int ra_charset_ok(request_rec *r); - возвращает 1, если
mod_charset уже успешно обработал этот запрос т.е определил кодировку
сервера и клиента. В противном случае возвращается 0.
Эту функцию нужно вызывать для каждого нового запроса по меньшей мере один раз.
В случае, если ra_charset_ok()==0, все прочие функции API могут вернуть 0 или
NULL и не надо этому удивляться.
int ra_no_of_charsets(request_rec *r); - возвращает
число различных charsets, известных серверу.
char * ra_charset_name(request_rec *r, int n); - возвращает
имя charset номер n (считая от нуля) в виде указателя на zero-terminated string.
int ra_charset_index(request_rec *r, const char* charset);
номер charset, если он известен серверу и -1 в противном случае.
char * ra_server_charset(request_rec *r); - возвращает имя
charset сервера (т.е. кодировку в которой mod_charset рассчитывает получить данные
от модуля/скрипта/из файла). Возвращаемое значение совпадает с значением
CGI-переменной SOURCE_CHARSET.
char * ra_client_charset(request_rec *r); - возвращает имя
кодировки клиента.
Функции, осуществляющие перекодировку
Все эти функции помещают перекодированную строку во внутренний storage в структуре
request_rec, поэтому каждый последующий вызов портит предыдущие перекодированные
данные. Соответствено, если перекодированные данные будут нужны после следующего
вызова ra_str_*/ra_data_*, необходимо самому скопировать результаты предшествующей
перекодировки в сухое и темное место. Данные, перекодирумые функциями client2server
и server2client хранятся в независимых storage.
char *ra_str_client2server(request_rec *r, const char* str); -
перекодирует zero-terminated строку strиз кодировки клиента в кодировку
сервера и возвращает указатель на перекодированную
строку.
Перекодировка производится "по байтам", конструкции вида %AA не перекодируются.
char *ra_str_server2client(request_rec *r, const char* str); -
перекодирует zero-terminated строку strиз кодировки сервера в кодировку
клиента и возвращает указатель на перекодированную
строку.
Перекодировка производится "по байтам", конструкции вида %AA не перекодируются.
char *ra_str_client2server_esc(request_rec *r, const char* str); -
перекодирует zero-terminated строку strиз кодировки клиента в кодировку
сервера и возвращает указатель на перекодированную
строку.
Эта функция корректно перекодирует escaped-конструкции вида %AA, причем в результирующей
строке на их место тоже будут вставлены escaped-символы.
char *ra_str_server2clien_esc(request_rec *r, const char* str); -
перекодирует zero-terminated строку strиз кодировки сервера в кодировку
клиента и возвращает указатель на перекодированную
строку.
Эта функция корректно перекодирует escaped-конструкции вида %AA, причем в результирующей
строке на их место тоже будут вставлены escaped-символы.
void ra_data_client2server(request_rec *r, const unsigned char* data, unsigned int nbytes, unsigned char **result, unsigned int *rnbytes); -
перекодирует nbytes данных, переданных указателем data. Возвращает указатель
на перекодированные данные в *result, в *rnbytes
помещается длина перекодированных данных (она может быть другой в общем случае).
Перекодировка производится из кодировки клиента в кодировку сервера.
void ra_data_server2client(request_rec *r, const unsigned char* data, unsigned int nbytes, unsigned char **result, unsigned int *rnbytes); -
перекодирует nbytes данных, переданных указателем data. Возвращает указатель
на перекодированные данные в *result, в *rnbytes
помещается длина перекодированных данных (она может быть другой в общем случае).
Перекодировка производится из кодировки сервера в кодировку клиента.
void ra_data_server2client_esc(request_rec *r, const unsigned char* data, unsigned int nbytes, unsigned char **result, unsigned int *rnbytes); void ra_data_server2client_esc(request_rec *r, const unsigned char* data, unsigned int nbytes, unsigned char **result, unsigned int *rnbytes);
- аналогично двум предшествующим функциям, но с корректной обработкой %AA-escapes.
char *ra_recode_str(request_rec *r, pool *p, const char *charset_from, const char *charset_to, const char *str)
Перекодирует строку str из charset_from в charset_to, возвращает перекодированную
строку. Если для данного сочетания charsets сервер не знает таблиц перекодировки,
то возвращает NULL.
Результаты перекодировки хранятся в pool *p.
Не поддерживает "широкие" таблицы перекодировки (т.е. translit).
char *ra_recode_str_esc(const char *charset_from, const char *charset_to, const char *str)
Перекодирует строку str из charset_from в charset_to, возвращает перекодированную
строку. Если для данного сочетания charsets сервер не знает таблиц перекодировки,
то возвращает NULL. Корректно преобразует %AA-escapes.
Результаты перекодировки хранятся в pool *p.
Не поддерживает "широкие" таблицы перекодировки (т.е. translit).
void ra_recode_data(const char *charset_from, const char *charset_to, const unsigned char *data, const unsigned datalen,unsigned char ** result, unsigned int *rlen)
Перекодирует данные data из charset_from в charset_to, возвращает перекодированные
данные в *result, их длину - в *rlen.
Если для данного сочетания charsets сервер не знает таблиц перекодировки,
то возвращает NULL.
Результаты перекодировки хранятся в pool *p.
Не поддерживает "широкие" таблицы перекодировки (т.е. translit).
void ra_recode_data_esc(const char *charset_from, const char *charset_to, const unsigned char *data, const unsigned datalen,unsigned char ** result, unsigned int *rlen)
Перекодирует данные data из charset_from в charset_to, возвращает перекодированные
данные в *result, их длину - в *rlen.
Если для данного сочетания charsets сервер не знает таблиц перекодировки,
то возвращает NULL. Корректно преобразует %AA-escapes.
Результаты перекодировки хранятся в pool *p.
Не поддерживает "широкие" таблицы перекодировки (т.е. translit).
Russian Apache Perl API
Perl API находится в стадии разработки, но в общих чертах повторяет C API.
Модуль для mod_perl, реализующий
Perl API будет доступен после выхода Russian Apache PL27.0
Если у вас есть замечания, изменения или дополнения к этому документу,
присылайте их прямо автору.
"Russian Apache" includes software developed
by the Apache Group for use in the Apache HTTP server project
(http://www.apache.org/) See
Apache LICENSE.
Copyright (C) 1995-2001 The Apache Group. All rights reserved.
Copyright (C) 1996 Dm. Kryukov; Copyright (C)
1997-2009 Alex Tutubalin. Design (C) 1998 Max Smolev.