<-
Apache > HTTP Server > Documentation > Version 2.0 > Developer Documentation

Apacheские 1.3 примечания программного интерфейса приложения

предупреждение

этот документ не был обновлен, чтобы принять во внимание изменения, сделанные в 2.0 версиях Apacheского Сервера HTTP. Часть информации может все еще быть уместной, но пожалуйста используйте это с заботой.

они - некоторые примечания относительно Apacheского программного интерфейса приложения и структур данных, Вы должны иметь дело с, и т.д. они еще не почти полны, но, мы надеемся, они помогут Вам получать ваши отношения. Имейте в виду, что программный интерфейс приложения все еще подчинен, чтобы измениться, поскольку мы приобретаем опыт с этим. (См. файл TODO для какой мог бы приехать). Однако, будет легко приспособить модули к любым изменениям, которые сделаны. (Мы имеем больше модулей, чтобы приспособиться, чем Вы делаете).

несколько примечаний относительно общего педагогического стиля здесь. В интересе краткости, все декларации структуры здесь неполны - реальные имеют больше щелей, о которых я не говорю Вам. Главным образом, они сохранены к одному компоненту ядра сервера или другого, и должны быть изменены модулями с предостережением. Однако, в некоторых случаях, они действительно - вещи, для которых я только не нашел время все же. Добро пожаловать в истекающий кровью край.

наконец, вот - схема, давать Вам некоторую голую идею относительно того, что подошло, и в какой заказ:

top

Basic concepts

мы начинаем с краткого обзора фундаментальных понятий позади программного интерфейса приложения, и как они проявлены в кодексе.

Handlers, Modules, and Requests

Apache ломает обработку запроса в ряд шагов, более или менее тот же самый способ, которым программный интерфейс приложения сервера Netscape делает (хотя этот программный интерфейс приложения имеет еще несколько стадий чем NetSite, делает, как крюки для материала, я думал, мог бы быть полезным в будущем). Они:

эти фазы обработаны, смотря на каждую последовательность модули , выглядя видят, имеет ли каждый из них тренера для фазы, и делающий попытку призыва этого если так. Тренер может типично делать одну из трех вещей:

большинство фаз закончено первым модулем, который обращается с ними; однако, для заготовки леса, `fixups', и проверка установления подлинности недоступа, все тренеры всегда бегут (запрещение ошибки). Кроме того, фаза ответа уникальна в этом, модули могут объявить, что многократные тренеры для этого, через стол отправки включал тип MIME требуемого объекта. Модули могут объявить тренера фазы ответа, который может обращаться любой запрос, давая это ключ */* ( то есть. , спецификация типа MIME группового символа). Однако, тренеры группового символа только призваны, если сервер уже пробовал и был не в состоянии найти более определенного тренера ответа для типа MIME требуемого объекта (или ни один не существовал, или они все уменьшались).

сами тренеры - функции одного аргумента (a request_rec структура. смотри инфра), который возвращает целое число, как выше.

A brief tour of a module

в этом пункте, мы должны объяснить структуру модуля. Наш кандидат будет одним из более грязных, модуль CGI - это обращается и с подлинниками CGI и с ScriptAlias команда файла config. Это фактически более сложно чем большинство модулей, но если мы собираемся иметь только один пример, это мог бы также быть тот с его пальцами в каждом месте.

давайте начинаться с тренеров. Чтобы обращаться с подлинниками CGI, модуль объявляет тренера ответа для них. Из-за ScriptAlias , это также имеет тренеров для фазы перевода названия (чтобы признать ScriptAlias редактор URIs), проверяющая тип фаза (любой ScriptAlias запрос редактора напечатан как подлинник CGI).

модуль должен поддержать некоторых в (действительную) информацию сервера, а именно, ScriptAlias es в действительности; структура модуля поэтому содержит указатели на функции, который строит эти структуры, и на другой, который комбинирует двух из них (в случае, если главный сервер и действительный сервер оба имеют ScriptAlias объявленный es).

наконец, этот модуль содержит кодекс, чтобы обращаться ScriptAlias командовать собой. Этот специфический модуль только объявляет одну команду, но мог быть больше, таким образом модули имеют столы команды которые объявляют их команды, и описывают, где им разрешают, и как они должны быть призваны.

заключительное примечание относительно заявленных типов аргументов некоторых из этих команд: a pool является указателем на a объединение ресурса структура; они используются сервером, чтобы держать след памяти, которая была ассигнована, файлы открылись, и т.д. , или обслуживать специфический запрос, или обращаться с процессом конфигурирования. Тот путь, когда запрос - по (или, для объединения конфигурации, когда сервер повторно начинается), память может быть освобожден, и закрытые файлы, в массе , без любого имеющего необходимость написать явный кодекс, чтобы отследить их всех вниз и избавиться от них. Кроме того, a cmd_parms структура содержит различную информацию о config файле, прочитанном, и другой информации статуса, которая имеет иногда использование к функции, которая обрабатывает команду config-файла (, типа ScriptAlias ). Без дальнейшей суматохи, модуль непосредственно:

/* Declarations of handlers. */

int translate_scriptalias (request_rec *);
int type_scriptalias (request_rec *);
int cgi_handler (request_rec *);

/* Subsidiary dispatch table for response-phase
 * handlers, by MIME type */

handler_rec cgi_handlers[] = {
{ "application/x-httpd-cgi", cgi_handler },
{ NULL }
};

/* Declarations of routines to manipulate the
 * module's configuration info. Note that these are
 * returned, and passed in, as void *'s; the server
 * core keeps track of them, but it doesn't, and can't,
 * know their internal structure.
 */

void *make_cgi_server_config (pool *);
void *merge_cgi_server_config (pool *, void *, void *);

/* Declarations of routines to handle config-file commands */

extern char *script_alias(cmd_parms *, void *per_dir_config, char *fake, char *real);

command_rec cgi_cmds[] = {
{ "ScriptAlias", script_alias, NULL, RSRC_CONF, TAKE2,
"a fakename and a realname"},
{ NULL }
};

module cgi_module = {

STANDARD_MODULE_STUFF, NULL, /* initializer */ NULL, /* dir config creator */ NULL, /* dir merger */ make_cgi_server_config, /* server config */ merge_cgi_server_config, /* merge server config */ cgi_cmds, /* command table */ cgi_handlers, /* handlers */ translate_scriptalias, /* filename translation */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ type_scriptalias, /* type_checker */ NULL, /* fixups */ NULL, /* logger */ NULL /* header parser */ };
top

How handlers work

единственный аргумент тренерам - a request_rec структура. Эта структура описывает специфический запрос, который был сделан к серверу, от имени клиента. В большинстве случаев, каждая связь с клиентом производит только один request_rec структура.

A brief tour of the request_rec

request_rec содержит указатели на объединение ресурса, которое будет очищено, когда сервер закончен, обращаясь с запросом; к структурам, содержащим в-сервер и в-связь информацию, и наиболее важно, информация относительно запроса непосредственно.

самое важное такая информация является маленьким набором строк символов, описывающих признаки объекта, который требуют, включая его ТУРОВ, имя файла, довольный тип и довольное зашифровывание (эти являющиеся заполненным в переводом и тренерами чека типа, которые обращаются с запросом, соответственно).

другие обычно используемые пункты данных - столы, дающие удары головой ПАНТОМИМЫ на оригинальном запросе клиента, удары головой ПАНТОМИМЫ, которые будут посланы назад с ответом (к которому могут добавить модули по желанию), и переменные окружающей среды для любых подпроцессов, которые порождены прочь в ходе обслуживания запроса. Этими столами управляют, используя ap_table_get и ap_table_set рутины.

отметить что Content-type ценность удара головой не может быть установлен довольными тренерами модуля, использующими ap_table_*() рутины. Скорее это установлено, указывая content_type область в request_rec структура к соответствующей веренице. например. ,

r->content_type = "text/html";

наконец, есть указатели на две структуры данных, которые, в свою очередь, указывают на в-модуль структуры конфигурации. Определенно, они держат указатели на структуры данных, которые модуль строил, чтобы описать способ, которым это формировалось, чтобы работать в данном справочнике (через .htaccess файлы или <Directory> секции), для частных данных, которые это строило в ходе обслуживания запроса (таким образом тренеры модулей для одной фазы могут передать `примечания их тренерам для других фаз). Есть другой такой вектор конфигурации в server_rec структура данных, на которую указывают request_rec , который содержит в (действительные) данные конфигурации сервера.

вот - сокращенная декларация, давая области, обычно используемые:

struct request_rec {

pool *pool;
conn_rec *connection;
server_rec *server;

/* What object is being requested */

char *uri;
char *filename;
char *path_info;

char *args; /* QUERY_ARGS, if any */ struct stat finfo; /* Set by server core; * st_mode set to zero if no such file */

char *content_type;
char *content_encoding;

/* MIME header environments, in and out. Also,
 * an array containing environment variables to
 * be passed to subprocesses, so people can write
 * modules to add to that environment.
 *
 * The difference between headers_out and
 * err_headers_out is that the latter are printed
 * even on error, and persist across internal
 * redirects (so the headers printed for
 * ErrorDocument handlers will have them).
 */

table *headers_in;
table *headers_out;
table *err_headers_out;
table *subprocess_env;

/* Info about the request itself... */

int header_only; /* HEAD request, as opposed to GET */ char *protocol; /* Protocol, as given to us, or HTTP/0.9 */ char *method; /* GET, HEAD, POST,

etc.

*/ int method_number; /* M_GET, M_POST,

etc.

*/

/* Info for logging */

char *the_request;
int bytes_sent;

/* A flag which modules can set, to indicate that
 * the data being returned is volatile, and clients
 * should be told not to cache it.
 */

int no_cache;

/* Various other config info which may change
 * with .htaccess files
 * These are config vectors, with one void*
 * pointer for each module (the thing pointed
 * to being the module's business).
 */

void *per_dir_config; /* Options set in config files,

etc.

*/ void *request_config; /* Notes on *this* request */

};

Where request_rec structures come from

больше всего request_rec структуры построены, читая запрос HTTP от клиента, и заполняясь в областях. Однако, есть несколько исключений:

Handling requests, declining, and returning error codes

как обсуждено выше, каждый тренер, когда призвано, чтобы обращаться с деталью request_rec , должен возвратиться int указывать, что случилось. Это может или быть

отметить, что, если ошибочный кодекс возвратился, REDIRECT , тогда модуль должен поместить a Location в запросе headers_out , указывать, где клиент должен быть переадресован к .

Special considerations for response handlers

тренеры для большинства фаз делают их работу, просто устанавливая несколько областей в request_rec структура (или, в случае шашек доступа, просто, возвращая правильный ошибочный кодекс). Однако, тренеры ответа должны фактически послать запрос назад клиенту.

они должны начать, посылая удар головой ответа HTTP, используя функцию ap_send_http_header . (Вы не должны сделать ничего специального, чтобы пропустить посылку удара головой для запросов HTTP/0.9; функция выясняет самостоятельно, что это не должно сделать ничего). Если запрос отмечен header_only , это - все, что они должны сделать; они должны возвратиться после этого, не делая попытку дальнейшей продукции.

иначе, они должны произвести тело запроса, которое отвечает на клиента как соответствующий. Примитивы для этого ap_rputc и ap_rprintf , для внутренне произведенной продукции, и ap_send_fd , чтобы скопировать содержание некоторых FILE * прямо клиенту.

в этом пункте, Вы должны более или менее понять следующую часть кодекса, который является тренером, который обращается GET запросы, которые не имеют никакого более определенного тренера; это также показывает как условный GET s может быть обработан, если желательно сделать так в специфическом тренере ответа- ap_set_last_modified чеки против If-modified-since ценность, поставляемая клиентом, если таковые вообще имеются, и возвращениями соответствующий кодекс (который, если отличное от нуля, будет USE_LOCAL_COPY). Никакие подобные рассмотрения не просят ap_set_content_length , но это возвращает ошибочный кодекс для симметрии.

int default_handler (request_rec *r)
{
int errstatus;
FILE *f;

if (r->method_number != M_GET) return DECLINED;
if (r->finfo.st_mode == 0) return NOT_FOUND;

if ((errstatus = ap_set_content_length (r, r->finfo.st_size))
    || (errstatus = ap_set_last_modified (r, r->finfo.st_mtime)))
return errstatus;

f = fopen (r->filename, "r");

if (f == NULL) {
log_reason("file permissions deny server access", r->filename, r);
return FORBIDDEN;
}

register_timeout ("send", r);
ap_send_http_header (r);

if (!r->header_only) send_fd (f, r);
ap_pfclose (r->pool, f);
return OK;
}

наконец, если все это - слишком большой вызов, есть несколько путей из этого. Сначала прочь, как показано выше, тренер ответа, который еще не произвел никакой продукции, может просто возвратить ошибочный кодекс, когда сервер автоматически произведет ошибочный ответ. Во-вторых, это может плыть на плоскодонке некоторому другому тренеру, призывая ap_internal_redirect , который является, как внутренние машины переназначения, обсужденные выше призваны. Тренер ответа, который внутренне переадресовал, должен всегда возвращаться OK .

(призыв ap_internal_redirect от тренеров, которые нет тренеры ответа приведут к серьезному беспорядку).

Special considerations for authentication handlers

материал, который должен быть обсужден здесь подробно:

Special considerations for logging handlers

когда запрос внутренне переадресовал, есть вопрос того, что регистрировать. Апач обращается, это, связывая всю цепь переадресовывает в список request_rec структуры, которые пронизываются через r->prev и r->next указатели. request_rec то, который передают тренерам заготовки леса в таких случаях, - тот, который был первоначально построен для начального запроса от клиента; отметьте что bytes_sent область только будет правильна в последнем запросе в цепи (тот, для которого ответ фактически посылали).

top

Resource allocation and resource pools

одна из проблем письма и проектирования сервера объединения сервера - одно из предотвращения утечки, то есть, ассигнуя ресурсы (память, открытые файлы, и т.д. ), впоследствии не освобождая их. Машины объединения ресурса разработаны, чтобы облегчать препятствовать этому случаться, позволяя ресурс быть ассигнованным таким способом, что они автоматически выпущенный, когда сервер сделан с ними.

путем это работает следующие: память, которая ассигнована, файл, открылась, и т.д. , иметь дело со специфическим запросом привязаны к a объединение ресурса который ассигнован для запроса. Объединение - структура данных, которая непосредственно отслеживает рассматриваемые ресурсы.

когда запрос был обработан, объединение очищенный . в том пункте, вся память, связанная с этим выпущена для повторного использования, все файлы, связанные с этим закрыты, и любыми другими функциями уборки, которые связаны с объединением, управляют. Когда это закончено, мы можем быть уверенными, что весь ресурс, привязанный к объединению был выпущен, и что ни один из них не просочился.

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

должно быть отмечено, что использование машин объединения не вообще обязательно, за исключением ситуаций как заготовка леса тренеров, где Вы действительно должны регистрировать уборки, чтобы удостовериться, что файл системного журнала закрыт, когда сервер повторно начинается (это наиболее легко сделано при использовании функции ap_pfopen , который также принимает меры, чтобы основной описатель файла был закрыт прежде, чем любые детские процессы, типа для подлинников CGI, exec редактор), или в случае, если Вы используете машины перерыва (который все же даже не зарегистрирован здесь). Однако, есть две выгоды к использованию этого: ресурсы, ассигнованные объединению никогда не просачиваются (даже если Вы ассигнуете вереницу царапины, и только забываете об этом); также, для распределения памяти, ap_palloc является вообще быстрее чем malloc .

мы начинаем здесь, описывая, как память ассигнована объединениям, и затем обсуждать, как другие ресурсы отслежены машинами объединения ресурса.

распределение памяти в объединениях

память ассигнована объединениям, называя функцию ap_palloc , который берет два аргумента, один являющийся указателем на структуру объединения ресурса, и другой являющийся количеством памяти, чтобы ассигновать (в char s). В пределах тренеров для того, чтобы обращаться с запросами, самый общий способ получать структуру объединения ресурса-, смотря pool щель уместного request_rec ; следовательно повторное появление следующей идиомы в кодексе модуля:

int my_handler(request_rec *r)
{
struct my_structure *foo;
...

foo = (foo *)ap_palloc (r->pool, sizeof(my_structure));
}

отметить это есть нет ap_pfree -- ap_palloc память редактора освобождена только, когда связанное объединение ресурса очищено. Это означает это ap_palloc не должен сделать такого большого бухгалтерского учета как malloc() ; все, что это делает в типичном случае, должно окружить размер, ударить указатель, и сделать чек диапазона.

(это также поднимает возможность то тяжелое использование ap_palloc мог заставить процесс сервера становиться чрезмерно большим. Есть два способа иметь дело с этим, с которыми имеют дело ниже; кратко, Вы можете использовать malloc , и попытка убедиться, что вся память добирается явно free d, или Вы можете ассигновать подобъединение главного объединения, ассигновать вашу память в подобъединении, и убрать это периодически. Последняя техника обсуждена в секции на подобъединениях ниже, и используется во вносящем в указатель справочник кодексе, чтобы избежать чрезмерного распределения хранения, перечисляя справочники с тысячами файлов).

распределение калибровавшей памяти

есть функции, которые ассигнуют калибровавшую память, и часто полезны. Функция ap_pcalloc имеет тот же самый интерфейс как ap_palloc , но убирает память, которую это ассигнует прежде, чем это возвращает это. Функция ap_pstrdup берет объединение ресурса и a char * как аргументы, и ассигнует память для копии вереницы, на которую указатель указывает, возвращая указатель на копию. Наконец ap_pstrcat является функцией varargs-стиля, которая берет указатель на объединение ресурса, и по крайней мере два char * аргументы, последние из которых должны быть NULL . это ассигнует достаточно памяти, чтобы соответствовать копиям каждой из верениц, как единица; например:

ap_pstrcat (r->pool, "foo", "/", "bar", NULL);

возвращает указатель на 8-байтовую ценность памяти, калибровавшей к "foo/bar" .

Commonly-used pools in the Apache Web server

объединение действительно определяется его целой жизнью больше чем что - нибудь еще. Есть некоторые статические объединения в http_main, которые передают к различным функциям non-http_main как аргументы в подходящие времена. Здесь они:

permanent_pool
никогда передаваемый к чему - нибудь еще, это не предок всех объединений
pconf
  • подобъединение permanent_pool
  • созданный в начале config "цикла"; существует, пока сервер не закончен или повторно начинается; переданный ко всем config-разовым рутинам, или через cmd->pool, или как "объединение *p" аргумент на тех, которые не берут объединения
  • переданный к модулю init () функции
ptemp
  • жаль я лежу, это объединение не называют этим в настоящее время в 1.3, я переименовал это это в моем pthreads развитии. Я отношу к использованию ptrans на родительском контрасте ... это с более поздним определением ptrans в ребенке.
  • подобъединение permanent_pool
  • созданный в начале config "цикла"; существует до конца парсинга config; переданный к config-разовым рутинам через cmd->temp_pool. Своего рода "побочный ребенок", потому что это не доступно всюду. Используемый для временного места царапины, которое может быть необходимо небольшим количеством config рутин, но который удалено в конце config.
pchild
  • подобъединение permanent_pool
  • созданный, когда ребенок порожден (или нить создан); жизни до того ребенка (нить) разрушены
  • переданный к модулю child_init функции
  • разрушение случается прямо после того, как функции child_exit называют ... (который может объяснить, почему я думаю, что child_exit избыточен и ненужен),
ptrans
  • должен быть подобъединение pchild, но в настоящее время - подобъединение permanent_pool, видеть выше
  • очищенный ребенком перед входом в принятие () петля, чтобы получить связь
  • используемый как connection->pool
r->pool
  • для главного запроса это - подобъединение connection->pool; для подзапросов это - подобъединение объединения родительского запроса.
  • существует до конца запроса ( то есть. , ap_destroy_sub_req, или в child_main после того, как process_request закончился),
  • отметить, что сам r ассигнован от r->pool; то есть. , r->pool сначала создан, и затем r - первая вещь palloc () d от этого

для почти всего люди делают, r->pool является объединением, чтобы использовать. Но Вы можете видеть, как другие сроки службы, типа pchild, являются полезными для некоторых модулей ..., типа модулей, которые должны открыть связь базы данных однажды в ребенка, и желать очистить это, когда ребенок умирает.

Вы можете также видеть, как немного ошибок проявили themself, типа урегулирования connection->user к ценности от r->pool - в этом случае связь существует для целой жизни ptrans , который более длинен чем r->pool (особенно, если r->pool является подзапросом!). Таким образом правильная вещь, чтобы сделать должна ассигновать от connection->pool .

и была другая интересная ошибка в mod_include / mod_cgi . Вы будете видеть в тех, что они делают этот тест, чтобы решить, должны ли они использовать r->pool или r->main->pool . в этом случае ресурс, который они регистрируют для уборки, - детский процесс. Если это было зарегистрировано в r->pool , тогда кодекс wait() для ребенка, когда подзапрос заканчивается. С mod_include это могло быть любым старый #include , и задержка может быть до 3 секунд ... и случилась весьма часто. Вместо этого подпроцесс зарегистрирован в r->main->pool который заставляет это быть вымытым, когда весь запрос сделан- то есть. , после того, как продукцию послали клиенту, и заготовка леса случилась.

Tracking open files, etc.

как обозначено выше, объединения ресурса также используются, чтобы отследить другие виды ресурсов помимо памяти. Самые общие - открытые файлы. Рутина, которая типично используется для этого, ap_pfopen , который берет объединение ресурса и две вереницы как аргументы; вереницы - то же самое как типичные аргументы fopen , например. ,

...
FILE *f = ap_pfopen (r->pool, r->filename, "r");

if (f == NULL) { ... } else { ... }

есть также a ap_popenf рутина, которая параллельна низшего уровня open запрос системы. Обе из этих рутин принимают меры, чтобы файл был закрыт, когда рассматриваемое объединение ресурса очищено.

в отличие от случая для памяти, там функции, чтобы закрыть файлы, ассигнованные с ap_pfopen , и ap_popenf , а именно, ap_pfclose и ap_pclosef . (это - то, потому что, на многих системах, число файлов, которые единственный процесс может иметь открытый, весьма ограничено). Важно использовать эти функции, чтобы закрыть файлы, ассигнованные с ap_pfopen и ap_popenf , с тех пор чтобы сделать иначе мог вызвать фатальные ошибки на системах, типа Linux, которые реагируют ужасно если то же самое FILE* закрыт не раз.

(Используя close функции не принудительны, так как файл будет в конечном счете закрыт независимо, но Вы должны рассмотреть это в случаях, где ваш модуль открывается, или мог открыться, много файлов).

другие виды ресурсов - функций уборки

больше текста идет сюда. Опишите примитивы уборки, в терминах которых осуществлен материал файла; также, spawn_process .

уборки объединения, живые до clear_pool() называется: clear_pool(a) рекурсивно запросы destroy_pool() на всех подобъединениях a ; тогда запросы все уборки для a ; тогда выпуски вся память для a . destroy_pool(a) запросы clear_pool(a) и затем выпускает структуру объединения непосредственно. то есть. , clear_pool(a) не удаляет a , это только освобождает все ресурсы, и Вы можете начать использовать это снова немедленно.

прекрасный контроль - создание и контакт с подобъединениями, с примечанием относительно подзапросов

в редких случаях, также-без использование ap_palloc() и связанные примитивы могут привести к непо желанию расточительному распределению ресурса. Вы можете иметь дело с таким случаем, создавая a подобъединение , распределение в пределах подобъединения, а не главного объединения, и очищая или разрушая подобъединение, которое выпускает ресурсы, которые были связаны с этим. (Это действительно редкая ситуация; единственный случай, в котором это подошло в стандартном наборе модуля, - в случае внесения в список справочников, и затем только с очень большие справочники. Ненужное использование примитивов, обсужденных здесь может волосы ваш кодекс весьма немного, с очень небольшой выгодой).

примитив чтобы создавать подобъединение ap_make_sub_pool , который берет другое объединение (родительское объединение) как аргумент. Когда главное объединение очищено, подобъединение будет разрушено. Подобъединение может также быть очищено или разрушено в любое время, называя функции ap_clear_pool и ap_destroy_pool , соответственно. (Различие - это ap_clear_pool освобождает ресурсы, связанные с объединением, в то время как ap_destroy_pool также освобождает объединение непосредственно. В прежнем случае, Вы можете ассигновать новые ресурсы в пределах объединения, и очистить это снова, и т.д; в последнем случае, это просто ушло).

одно заключительное примечание - подзапросы имеют их собственные объединения ресурса, которые являются подобъединениями объединения ресурса для главного запроса. Вежливый способ исправлять ресурсы связался с запросом sub, который Вы ассигновали (использование ap_sub_req_... функции) ap_destroy_sub_req , который освобождает объединение ресурса. Перед запросом этой функции, убедитесь, что скопировали что - нибудь, что Вы заботитесь, о котором мог бы быть ассигнован в объединении ресурса подзапроса в где-нибудь немного менее изменчивый (например, имя файла в request_rec структура).

(снова, при большинстве обстоятельств, Вы не должны чувствовать себя обязанными назвать эту функцию; только 2 КБ памяти или так ассигнованы для типичного запроса sub, и это будет освобождено так или иначе, когда главное объединение запроса очищено. Только, когда Вы ассигнуете многих, много подзапросов о единственном главном запросе, что Вы должны серьезно рассмотреть ap_destroy_... функции).

top

Configuration, commands and the like

одна из целей проекта для этого сервера состояла в том, чтобы поддержать внешнюю совместимость с NCSA 1.3 сервера---то есть, прочитать те же самые файлы конфигурации, обрабатывать все директивы там правильно, и вообще быть заглядывающейся заменой для NCSA. С другой стороны, другая цель проекта состояла в том, чтобы переместить такую большую из функциональных возможностей сервера в модули, которые как можно меньше имеют отношение к монолитному ядру сервера. Единственный способ урегулировать эти цели состоит в том, чтобы переместить обработку большинства команд от центрального сервера в модули.

однако, только предоставление модулей приказывает, чтобы столы недостаточно, чтобы развестись с ними полностью от ядра сервера. Сервер должен помнить команды, чтобы действовать на них позже. Это вовлекает данные поддержания, которые являются частными к модулям, и который могут быть или в-сервер, или в-справочник. Большинство вещей в-справочник, включая в специфический контроль доступа и информацию разрешения, но также и информацию относительно того, как определить типы файла от суффиксов, которые могут быть изменены AddType и DefaultType директивы, и т.д. Вообще, управляющая философия - то, что что - нибудь который может быть сделан конфигурируемым справочником, должен быть; в-сервер информация вообще используется в стандартном наборе модулей для информации как Alias es и Redirect s, которые входят в игру прежде, чем запрос привязан к специфическому месту в основной системе файла.

другое требование чтобы подражать серверу NCSA в состоянии обращаться со в-справочник файлами конфигурации, вообще называемыми .htaccess файлы, хотя даже в сервере NCSA они могут содержать директивы, которые не имеют ничего вообще, чтобы сделать с контролем доступа. Соответственно, после ТУРОВ -> перевод имени файла, но перед выполнением любой другой фазы, сервер спускается с директивной иерархии основной файловой системы, после переведенного имени пути, прочитать любого .htaccess файлы, которые могли бы присутствовать. Информация, которая прочитана в тогда, должна быть слитый с применимой информацией от собственных config файлов сервера (любой от <Directory> секции в access.conf , или от неплатежей в srm.conf , который фактически ведет себя в большинстве целей почти точно как <Directory /> ).

наконец, служа запросу, который вовлекал чтение .htaccess файлы, мы должны отказаться от хранения, ассигнованного для того, чтобы обращаться с ними. Это решено тем же самый путем, это решено везде, где еще подобные проблемы подошли, связывая те структуры со в-сделку объединением ресурса.

Per-directory configuration structures

давайте выглядывать, как все это теряет значение в mod_mime.c , который определяет файл, печатающий тренера, который подражает поведению сервера NCSA определения типов файла от суффиксов. То, на что мы будем смотреть, здесь, кодекс, который осуществляет AddType и AddEncoding команды. Эти команды могут появиться в .htaccess файлы, таким образом они должны быть обработаны в частных в-справочник данных модуля, который фактически, состоят из двух отдельных столов для типов MIME и информации зашифровывания, и объявлены следующим образом:

typedef struct { table *forced_types; /* Additional AddTyped stuff */ table *encoding_types; /* Added with AddEncoding... */ } mime_dir_config;

когда сервер читает файл конфигурации, или <Directory> секция, которая включает одну из команд модуля ПАНТОМИМЫ, это должно создать a mime_dir_config структура, таким образом те команды имеют кое-что, чтобы действовать на. Это делает это, призывая функцию, которую это находит в модуле, `создают в-директора config щель', с двумя аргументами: название справочника, к которому применяется эта информация конфигурации (или NULL для srm.conf ), и указатель на ресурс объединяют, в котором должно случиться распределение.

(если мы читаем a .htaccess файл, то объединение ресурса - в-запрос объединение ресурса для запроса; иначе это - объединение ресурса, которое используется для данных конфигурации, и очищено на перезапусках. Любым путем, это важно для структуры, создаваемой, чтобы исчезнуть, когда объединение очищено, регистрируя уборку на объединении в случае необходимости).

для модуля ПАНТОМИМЫ, в-директора config функция создания только ap_palloc s структура выше, и создавание нескольких столов, чтобы заполнить это. Это похожо на это:

void *create_mime_dir_config (pool *p, char *dummy)
{
mime_dir_config *new =
(mime_dir_config *) ap_palloc (p, sizeof(mime_dir_config));

new->forced_types = ap_make_table (p, 4);
new->encoding_types = ap_make_table (p, 4);

return new;
}

теперь, предположите, что мы только что читали в a .htaccess файл. Мы уже имеем в-справочник структуру конфигурации для следующего справочника в иерархии. Если .htaccess файл, в котором мы только читаем, не имел никого AddType или AddEncoding команды, его в-справочник config структура для модуля ПАНТОМИМЫ все еще действительна, и мы можем только использовать это. Иначе, мы должны слить эти две структуры так или иначе.

чтобы сделать это, сервер призывает в-справочник функцию слияния config модуля, если Вы присутствуете. Та функция берет три аргумента: эти две структуры, сливаемые, и ресурс объединяют, чтобы ассигновать результат. Для модуля ПАНТОМИМЫ, все, что потребности, которые будут сделаны являются оверлейными столы от новой в-справочник config структуры с теми от родителя:

void *merge_mime_dir_configs (pool *p, void *parent_dirv, void *subdirv)
{
mime_dir_config *parent_dir = (mime_dir_config *)parent_dirv;
mime_dir_config *subdir = (mime_dir_config *)subdirv;
mime_dir_config *new =
(mime_dir_config *)ap_palloc (p, sizeof(mime_dir_config));

new->forced_types = ap_overlay_tables (p, subdir->forced_types,
parent_dir->forced_types);
new->encoding_types = ap_overlay_tables (p, subdir->encoding_types,
parent_dir->encoding_types);

return new;
}

как примечание - если нет никакого в-справочник подарка функции слияния, сервер будет только использовать информацию конфигурации подсправочника, и игнорировать родителя. Для некоторых модулей, который работает только прекрасный ( например. , для включает модуль, в-справочник информация конфигурации которого состоит исключительно из государства XBITHACK ), и для тех модулей, Вы не можете только объявить один, и оставить соответствующую щель структуры в модуле непосредственно NULL .

Command handling

теперь, когда мы имеем эти структуры, мы должны быть в состоянии выяснить, как заполнить их. Это вовлекает обработку фактического AddType и AddEncoding команды. Чтобы находить команды, сервер смотрит в столе команды модуля. Тот стол содержит информацию относительно того, сколько аргументов команды берут, и в том, какие форматы, где это разрешает, и т.д. Та информация достаточна, чтобы позволить серверу призывать большинство обращающих с командой функций с предразобранными аргументами. Без дальнейшей суматохи, давайте взгляд на AddType командовать тренером, который похож на это ( AddEncoding командовать взглядами в основном то же самое, и не будет показывать здесь):

char *add_type(cmd_parms *cmd, mime_dir_config *m, char *ct, char *ext)
{
if (*ext == '.') ++ext;
ap_table_set (m->forced_types, ext, ct);
return NULL;
}

этот тренер команды необычно прост. Поскольку Вы можете видеть, требуется четыре аргумента, два из которых - предразобранные аргументы, третье, являющееся в-справочник структурой конфигурации для модуля, рассматриваемого, и четвертого, являющегося указателем на a cmd_parms структура. Та структура содержит связку аргументов, которые имеют часто использование к некоторым, но не всем, командам, включая объединение ресурса (от которого память может быть ассигнована, и к которому уборки должны быть привязаны), и (действительный) формируемый сервер, от которого в-сервер данные конфигурации модуля могут быть получены если требуется.

иначе, в котором этот специфический тренер команды является необычно простым, - то, что нет никаких ошибочных условий, с которыми это может столкнуться. Если бы был, то это могло бы возвратить ошибочное сообщение вместо NULL ; это заставляет ошибку быть распечатанной на сервере stderr , сопровождаемый быстрым выходом, если это - в основном config файлы; для a .htaccess файл, ошибка синтаксиса загружена ошибочная регистрация сервера (наряду с признаком того, откуда это прибыло), и запрос выброшен с ошибочным ответом сервера (ошибочный статус HTTP, кодекс 500).

стол команды модуля ПАНТОМИМЫ имеет записи для этих команд, которые похожи на это:

command_rec mime_cmds[] = {
{ "AddType", add_type, NULL, OR_FILEINFO, TAKE2,
"a mime type followed by a file extension" },
{ "AddEncoding", add_encoding, NULL, OR_FILEINFO, TAKE2,
"an encoding ( e.g. , gzip), followed by a file extension" },
{ NULL }
};

записи в этих столах:

наконец, установив это все, мы должны использовать это. Это в конечном счете сделано в тренерах модуля, определенно для его печатающего файл тренера, который более или менее походит на это; отметьте, что в-справочник структура конфигурации извлечена из request_rec 's в-справочник вектор конфигурации при использовании ap_get_module_config функция.

int find_ct(request_rec *r)
{
int i;
char *fn = ap_pstrdup (r->pool, r->filename);
mime_dir_config *conf = (mime_dir_config *)
ap_get_module_config(r->per_dir_config, &mime_module);
char *type;

if (S_ISDIR(r->finfo.st_mode)) {
r->content_type = DIR_MAGIC_TYPE;
return OK;
}

if((i=ap_rind(fn,'.')) < 0) return DECLINED;
++i;

if ((type = ap_table_get (conf->encoding_types, &fn[i])))
{
r->content_encoding = type;

/* go back to previous extension to try to use it as a type */
fn[i-1] = '\0';
if((i=ap_rind(fn,'.')) < 0) return OK;
++i;
}

if ((type = ap_table_get (conf->forced_types, &fn[i])))
{
r->content_type = type;
}

return OK;
}

Side notes -- per-server configuration, virtual servers, etc .

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

единственное существенное различие - то, что, когда команда должна формировать в-сервер частные данные модуля, это должно пойти в cmd_parms данные, чтобы достигнуть это. Вот - пример, от модуля псевдонима, который также указывает, как ошибка синтаксиса может быть возвращена (отметьте, что в-справочник аргумент конфигурации тренеру команды объявлен как кукла, так как модуль фактически не имеет в-справочник config данных):

char *add_redirect(cmd_parms *cmd, void *dummy, char *f, char *url)
{
server_rec *s = cmd->server;
alias_server_conf *conf = (alias_server_conf *)
ap_get_module_config(s->module_config,&alias_module);
alias_entry *new = ap_push_array (conf->redirects);

if (!ap_is_url (url)) return "Redirect to non-URL";

new->fake = f; new->real = url;
return NULL;
}