Apache Версия 2.0 Сервера HTTP
этот документ не был обновлен, чтобы принять во внимание изменения, сделанные в 2.0 версиях Apacheского Сервера HTTP. Часть информации может все еще быть уместной, но пожалуйста используйте это с заботой.
они - некоторые примечания относительно Apacheского программного интерфейса приложения и структур данных, Вы должны иметь дело с, и т.д. они еще не почти полны, но, мы надеемся, они помогут Вам получать ваши отношения. Имейте в виду, что программный интерфейс приложения все еще подчинен, чтобы измениться, поскольку мы приобретаем опыт с этим. (См. файл TODO для какой мог бы приехать). Однако, будет легко приспособить модули к любым изменениям, которые сделаны. (Мы имеем больше модулей, чтобы приспособиться, чем Вы делаете).
несколько примечаний относительно общего педагогического стиля здесь. В интересе краткости, все декларации структуры здесь неполны - реальные имеют больше щелей, о которых я не говорю Вам. Главным образом, они сохранены к одному компоненту ядра сервера или другого, и должны быть изменены модулями с предостережением. Однако, в некоторых случаях, они действительно - вещи, для которых я только не нашел время все же. Добро пожаловать в истекающий кровью край.
наконец, вот - схема, давать Вам некоторую голую идею относительно того, что подошло, и в какой заказ:
мы начинаем с краткого обзора фундаментальных понятий позади программного интерфейса приложения, и как они проявлены в кодексе.
Apache ломает обработку запроса в ряд шагов, более или менее тот же самый способ, которым программный интерфейс приложения сервера Netscape делает (хотя этот программный интерфейс приложения имеет еще несколько стадий чем NetSite, делает, как крюки для материала, я думал, мог бы быть полезным в будущем). Они:
SetEnv
, который действительно не соответствует хорошо в другом месте.
эти фазы обработаны, смотря на каждую последовательность модули , выглядя видят, имеет ли каждый из них тренера для фазы, и делающий попытку призыва этого если так. Тренер может типично делать одну из трех вещей:
OK
.
DECLINED
. в этом случае, сервер ведет себя во всех отношениях, как будто тренер просто не был там.
большинство фаз закончено первым модулем, который обращается с ними; однако, для заготовки леса, `fixups', и проверка установления подлинности недоступа, все тренеры всегда бегут (запрещение ошибки). Кроме того, фаза ответа уникальна в этом, модули могут объявить, что многократные тренеры для этого, через стол отправки включал тип MIME требуемого объекта. Модули могут объявить тренера фазы ответа, который может обращаться
любой
запрос, давая это ключ
*/*
(
то есть.
, спецификация типа MIME группового символа). Однако, тренеры группового символа только призваны, если сервер уже пробовал и был не в состоянии найти более определенного тренера ответа для типа MIME требуемого объекта (или ни один не существовал, или они все уменьшались).
сами тренеры - функции одного аргумента (a
request_rec
структура. смотри инфра), который возвращает целое число, как выше.
в этом пункте, мы должны объяснить структуру модуля. Наш кандидат будет одним из более грязных, модуль 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 */ };
единственный аргумент тренерам - a
request_rec
структура. Эта структура описывает специфический запрос, который был сделан к серверу, от имени клиента. В большинстве случаев, каждая связь с клиентом производит только один
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 */
};
больше всего
request_rec
структуры построены, читая запрос HTTP от клиента, и заполняясь в областях. Однако, есть несколько исключений:
*.var
файл), или подлинник CGI, который возвратил местное `Местоположение:', тогда ресурс, который просил пользователь, собирается быть в конечном счете расположенным некоторыми ТУРАМИ кроме того, что первоначально поставлял клиент. В этом случае, сервер делает
внутренний переадресовывают
, строительство нового
request_rec
для новых ТУРОВ, и обработки этого почти точно, как будто клиент просил новых ТУРОВ непосредственно.
ErrorDocument
находится в возможностях, внутреннее то же самое переадресовывают машины, входит в игру.
наконец, тренер иногда должен исследовать, `что случилось бы, управляли ли' некоторым другим запросом. Например, директивный модуль индексации должен знать то, что тип MIME был бы назначен на запрос о каждом директивном входе, чтобы выяснить какой изображение использовать.
такие тренеры могут строить a
подзапрос
, использование функций
ap_sub_req_lookup_file
,
ap_sub_req_lookup_uri
, и
ap_sub_req_method_uri
; они строят новое
request_rec
структура и процессы это, поскольку Вы ожидали бы, до, но не включая пункт того, чтобы фактически посылать ответ. (Эти функции перескакивают через чеки доступа, если подзапрос - для файла в том же самом справочнике как оригинальный запрос).
(сторона сервера включает работу, строя подзапросы и затем фактически призывая тренера ответа для них, через функцию
ap_run_sub_req
).
как обсуждено выше, каждый тренер, когда призвано, чтобы обращаться с деталью
request_rec
, должен возвратиться
int
указывать, что случилось. Это может или быть
OK
- запрос был обработан успешно. Это может или, возможно, не закончить фазу.
DECLINED
- никакое ошибочное условие не существует, но модуль отказывается обращаться с фазой; сервер пробует найти другой.
отметить, что, если ошибочный кодекс возвратился,
REDIRECT
, тогда модуль должен поместить a
Location
в запросе
headers_out
, указывать, где клиент должен быть переадресован
к
.
тренеры для большинства фаз делают их работу, просто устанавливая несколько областей в
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
от тренеров, которые
нет
тренеры ответа приведут к серьезному беспорядку).
материал, который должен быть обсужден здесь подробно:
ap_auth_type
,
ap_auth_name
, и
ap_requires
.
ap_get_basic_auth_pw
, который устанавливает
connection->user
область структуры автоматически, и
ap_note_basic_auth_failure
, который устраивает надлежащее
WWW-Authenticate:
удар головой, который будет послан назад).
когда запрос внутренне переадресовал, есть вопрос того, что регистрировать. Апач обращается, это, связывая всю цепь переадресовывает в список
request_rec
структуры, которые пронизываются через
r->prev
и
r->next
указатели.
request_rec
то, который передают тренерам заготовки леса в таких случаях, - тот, который был первоначально построен для начального запроса от клиента; отметьте что
bytes_sent
область только будет правильна в последнем запросе в цепи (тот, для которого ответ фактически посылали).
одна из проблем письма и проектирования сервера объединения сервера - одно из предотвращения утечки, то есть, ассигнуя ресурсы (память, открытые файлы, и т.д. ), впоследствии не освобождая их. Машины объединения ресурса разработаны, чтобы облегчать препятствовать этому случаться, позволяя ресурс быть ассигнованным таким способом, что они автоматически выпущенный, когда сервер сделан с ними.
путем это работает следующие: память, которая ассигнована, файл, открылась, и т.д. , иметь дело со специфическим запросом привязаны к 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"
.
объединение действительно определяется его целой жизнью больше чем что - нибудь еще. Есть некоторые статические объединения в http_main, которые передают к различным функциям non-http_main как аргументы в подходящие времена. Здесь они:
permanent_pool
pconf
ptemp
pchild
ptrans
r->pool
для почти всего люди делают,
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
который заставляет это быть вымытым, когда весь запрос сделан-
то есть.
, после того, как продукцию послали клиенту, и заготовка леса случилась.
как обозначено выше, объединения ресурса также используются, чтобы отследить другие виды ресурсов помимо памяти. Самые общие - открытые файлы. Рутина, которая типично используется для этого,
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_...
функции).
одна из целей проекта для этого сервера состояла в том, чтобы поддержать внешнюю совместимость с NCSA 1.3 сервера---то есть, прочитать те же самые файлы конфигурации, обрабатывать все директивы там правильно, и вообще быть заглядывающейся заменой для NCSA. С другой стороны, другая цель проекта состояла в том, чтобы переместить такую большую из функциональных возможностей сервера в модули, которые как можно меньше имеют отношение к монолитному ядру сервера. Единственный способ урегулировать эти цели состоит в том, чтобы переместить обработку большинства команд от центрального сервера в модули.
однако, только предоставление модулей приказывает, чтобы столы недостаточно, чтобы развестись с ними полностью от ядра сервера. Сервер должен помнить команды, чтобы действовать на них позже. Это вовлекает данные поддержания, которые являются частными к модулям, и который могут быть или в-сервер, или в-справочник. Большинство вещей в-справочник, включая в специфический контроль доступа и информацию разрешения, но также и информацию относительно того, как определить типы файла от суффиксов, которые могут быть изменены
AddType
и
DefaultType
директивы, и т.д. Вообще, управляющая философия - то, что что - нибудь который
может
быть сделан конфигурируемым справочником, должен быть; в-сервер информация вообще используется в стандартном наборе модулей для информации как
Alias
es и
Redirect
s, которые входят в игру прежде, чем запрос привязан к специфическому месту в основной системе файла.
другое требование чтобы подражать серверу NCSA в состоянии обращаться со в-справочник файлами конфигурации, вообще называемыми
.htaccess
файлы, хотя даже в сервере NCSA они могут содержать директивы, которые не имеют ничего вообще, чтобы сделать с контролем доступа. Соответственно, после ТУРОВ -> перевод имени файла, но перед выполнением любой другой фазы, сервер спускается с директивной иерархии основной файловой системы, после переведенного имени пути, прочитать любого
.htaccess
файлы, которые могли бы присутствовать. Информация, которая прочитана в тогда, должна быть
слитый
с применимой информацией от собственных config файлов сервера (любой от
<Directory>
секции в
access.conf
, или от неплатежей в
srm.conf
, который фактически ведет себя в большинстве целей почти точно как
<Directory />
).
наконец, служа запросу, который вовлекал чтение
.htaccess
файлы, мы должны отказаться от хранения, ассигнованного для того, чтобы обращаться с ними. Это решено тем же самый путем, это решено везде, где еще подобные проблемы подошли, связывая те структуры со в-сделку объединением ресурса.
давайте выглядывать, как все это теряет значение в
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
.
теперь, когда мы имеем эти структуры, мы должны быть в состоянии выяснить, как заполнить их. Это вовлекает обработку фактического
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 }
};
записи в этих столах:
(void *)
указатель, который передают в
cmd_parms
структура тренеру команды---это полезна в случае, если много подобных команд обработаны той же самой функцией.
AllowOverride
выбор, и дополнительный бит маски,
RSRC_CONF
, указывая, что команда может появиться в собственных config файлах сервера, но
нет
в любом
.htaccess
файл.
TAKE2
указывает два предразобранных аргумента. Другие варианты
TAKE1
, который указывает, что тот предразобрал аргумент,
FLAG
, который указывает, что аргумент должен быть
On
или
Off
, в и передается как булевый флаг,
RAW_ARGS
, который заставляет сервер давать команде сырые, неразобранные аргументы (все кроме названия команды непосредственно). Есть также
ITERATE
, что означает, что тренер выглядит одинаково как
TAKE1
, но что, если многократные аргументы присутствуют, это нужно назвать многократными временами, и наконец
ITERATE2
, который указывает, что тренер команды похож на a
TAKE2
, но если больше аргументов присутствует, то это нужно назвать многократными временами, держа первый постоянный аргумент.
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;
}
основные идеи позади в-сервер конфигурации модуля - в основном то же самое как те для в-справочник конфигурации; есть функция создания и функция слияния, последний, призываемый, где действительный сервер частично отверг основную конфигурацию сервера, и объединенная структура должна быть вычислена. (Как со в-справочник конфигурацией, неплатеж, если никакая функция слияния не определена, и модуль, формируется в некотором действительном сервере, - то, что основная конфигурация просто игнорируется).
единственное существенное различие - то, что, когда команда должна формировать в-сервер частные данные модуля, это должно пойти в
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;
}