>
>
>+ if (ctinfo) {
>+ if (ctinfo->output_filters && r->proxyreq == PROXYREQ_NONE) {
>+ const char *filter, *filters = ctinfo->output_filters;
>+ while (*filters
>+ && (filter = ap_getword(r->pool, &filters, ';'))) {
>+ ap_add_output_filter(filter, NULL, r, r->connection);
>+ }
>+ }
>+ }
>
This reminds me: mod_mime needs some performance work.
I probably won't have time to address this between now
and 2.0 GA, and the performance problem isn't big
enough to be a GA showstopper, but I'll summarize the
issues here in case anyone else is interested in tackling
the problem.
* With this patch, there are now two loops in find_ct()
that use ap_getword() to separate words from a
semicolon-delimited list on every request. This parsing
really should happen at config time, not request time.
* Also, the ap_add_output_filter() call is somewhat slow.
It runs in roughly O(n) time, where n==strlen(filter).
The O(1)-time alternative is to use ap_add_output_filter_handle()
in cases where it's possible to do the filter-name-to-filter
lookup in advance.
A faster approach would be to store the filter metadata as
a list of objects, instead of a semicolon-delimited string:
During config processing, pre-parse the semicolon-delimited
list, and create a linked list out of the filter names.
Then, for each filter name in the list, try to look up the
filter associated with that name. If the lookup succeeds,
store the corresponding filter handle in that node in the
linked list. (Even if a new filter is later installed with
the same name, that's okay; the filter handle is a pointer-to-
pointer object that will always point to whatever the current
filter for that name is.)
With this list created during config processing, the request
processing would look something like this:
for each node N in the linked list {
if (N->filter_handle != NULL) {
ap_add_output_filter_handle(N->filter_handle, ...);
}
else {
ap_add_output_filter(N->filter_name, ...);
}
}
--Brian