From: Paul Querna Date: Mon, 5 Sep 2005 00:21:25 +0000 (+0000) Subject: *) Create an optional function and MPM Query to replace the core output filter. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c05049bff60ff9a72a15c488b1f684eaf4d0088;p=thirdparty%2Fapache%2Fhttpd.git *) Create an optional function and MPM Query to replace the core output filter. *) Put an example of using it into the Event MPM, which just calls the original core output filter. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/async-dev@278652 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index d12a117ba26..4be46983c10 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.0 [Remove entries to the current 2.0 and 2.2 section below, when backported] + *) Enable MPMs to easily override the core output filter. + [Paul Querna] + *) httpd.exe/apachectl -V: display the DYNAMIC_MODULE_LIMIT setting, as in 1.3. [Jeff Trawick] diff --git a/include/ap_mpm.h b/include/ap_mpm.h index 405580b0eab..2ead406001a 100644 --- a/include/ap_mpm.h +++ b/include/ap_mpm.h @@ -146,6 +146,7 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process( #define AP_MPMQ_MAX_DAEMONS 12 /* Max # of daemons by config */ #define AP_MPMQ_MPM_STATE 13 /* starting, running, stopping */ #define AP_MPMQ_IS_ASYNC 14 /* MPM can process async connections */ +#define AP_MPMQ_CUSTOM_WRITE 15 /* MPM uses a custom output filter */ /** * Query a property of the current MPM. diff --git a/include/util_filter.h b/include/util_filter.h index 0f29aaa5dda..e49141cef26 100644 --- a/include/util_filter.h +++ b/include/util_filter.h @@ -24,6 +24,7 @@ #include "apr.h" #include "apr_buckets.h" +#include "apr_optional.h" #include "httpd.h" @@ -587,6 +588,9 @@ AP_DECLARE(void) ap_filter_protocol(ap_filter_t* f, unsigned int proto_flags); /** Filter is incompatible with "Cache-Control: no-transform" */ #define AP_FILTER_PROTO_TRANSFORM 0x20 +APR_DECLARE_OPTIONAL_FN(apr_status_t, ap_mpm_custom_write_filter, + (ap_filter_t *f, apr_bucket_brigade *b)); + #ifdef __cplusplus } #endif diff --git a/server/core.c b/server/core.c index 150f361e95e..41796c498e3 100644 --- a/server/core.c +++ b/server/core.c @@ -21,6 +21,7 @@ #include "apr_hash.h" #include "apr_thread_proc.h" /* for RLIMIT stuff */ #include "apr_hooks.h" +#include "apr_optional.h" #define APR_WANT_IOVEC #define APR_WANT_STRFUNC @@ -48,6 +49,7 @@ #include "mod_core.h" #include "mod_proxy.h" #include "ap_listen.h" +#include "ap_mpm.h" #include "mod_so.h" /* for ap_find_loaded_module_symbol */ @@ -90,10 +92,13 @@ AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, /* Handles for core filters */ AP_DECLARE_DATA ap_filter_rec_t *ap_subreq_core_filter_handle; AP_DECLARE_DATA ap_filter_rec_t *ap_core_output_filter_handle; +AP_DECLARE_DATA ap_filter_rec_t *ap_core_mpm_write_filter_handle; AP_DECLARE_DATA ap_filter_rec_t *ap_content_length_filter_handle; AP_DECLARE_DATA ap_filter_rec_t *ap_net_time_filter_handle; AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; +static APR_OPTIONAL_FN_TYPE(ap_mpm_custom_write_filter) *mpm_write_func; + /* magic pointer for ErrorDocument xxx "default" */ static char errordocument_default; @@ -3676,9 +3681,25 @@ APR_OPTIONAL_FN_TYPE(ap_logio_add_bytes_out) *logio_add_bytes_out; static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { + int mpm_write = 0; + logio_add_bytes_out = APR_RETRIEVE_OPTIONAL_FN(ap_logio_add_bytes_out); ident_lookup = APR_RETRIEVE_OPTIONAL_FN(ap_ident_lookup); + if (ap_mpm_query(AP_MPMQ_CUSTOM_WRITE, &mpm_write) == APR_SUCCESS + && mpm_write == 1) { + mpm_write_func = APR_RETRIEVE_OPTIONAL_FN(ap_mpm_custom_write_filter); + + ap_core_output_filter_handle = + ap_register_output_filter("CORE", mpm_write_func, + NULL, AP_FTYPE_NETWORK); + } + else { + ap_core_output_filter_handle = + ap_register_output_filter("CORE", ap_core_output_filter, + NULL, AP_FTYPE_NETWORK); + } + ap_set_version(pconf); ap_setup_make_content_type(pconf); return OK; @@ -3853,7 +3874,10 @@ static int core_pre_connection(conn_rec *c, void *csd) ap_set_module_config(net->c->conn_config, &core_module, csd); ap_add_input_filter_handle(ap_core_input_filter_handle, net, NULL, net->c); - ap_add_output_filter_handle(ap_core_output_filter_handle, net, NULL, net->c); + + ap_add_output_filter_handle(ap_core_output_filter_handle, net, + NULL, net->c); + return DONE; } @@ -3898,9 +3922,8 @@ static void register_hooks(apr_pool_t *p) ap_content_length_filter_handle = ap_register_output_filter("CONTENT_LENGTH", ap_content_length_filter, NULL, AP_FTYPE_PROTOCOL); - ap_core_output_filter_handle = - ap_register_output_filter("CORE", ap_core_output_filter, - NULL, AP_FTYPE_NETWORK); + + ap_subreq_core_filter_handle = ap_register_output_filter("SUBREQ_CORE", ap_sub_req_output_filter, NULL, AP_FTYPE_CONTENT_SET); diff --git a/server/mpm/experimental/event/Makefile.in b/server/mpm/experimental/event/Makefile.in index 7c2a1a7a6df..955303a19e0 100644 --- a/server/mpm/experimental/event/Makefile.in +++ b/server/mpm/experimental/event/Makefile.in @@ -1,5 +1,5 @@ LTLIBRARY_NAME = libevent.la -LTLIBRARY_SOURCES = event.c fdqueue.c pod.c +LTLIBRARY_SOURCES = event.c event_filters.c fdqueue.c pod.c include $(top_srcdir)/build/ltlib.mk diff --git a/server/mpm/experimental/event/event.c b/server/mpm/experimental/event/event.c index 4ccd0caf6f7..d51163c4d1b 100644 --- a/server/mpm/experimental/event/event.c +++ b/server/mpm/experimental/event/event.c @@ -168,6 +168,9 @@ static struct timeout_head_t timeout_head; static apr_pollset_t *event_pollset; +extern apr_status_t ap_mpm_custom_write_filter(ap_filter_t *f, + apr_bucket_brigade *bb); + /* The structure used to pass unique initialization info to each thread */ typedef struct { @@ -336,6 +339,9 @@ AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result) case AP_MPMQ_IS_ASYNC: *result = 1; return APR_SUCCESS; + case AP_MPMQ_CUSTOM_WRITE: + *result = 1; + return APR_SUCCESS; case AP_MPMQ_HARD_LIMIT_DAEMONS: *result = server_limit; return APR_SUCCESS; @@ -2203,6 +2209,8 @@ static void event_hooks(apr_pool_t * p) * to retrieve it, so register as REALLY_FIRST */ ap_hook_pre_config(worker_pre_config, NULL, NULL, APR_HOOK_REALLY_FIRST); + + APR_REGISTER_OPTIONAL_FN(ap_mpm_custom_write_filter); } static const char *set_daemons_to_start(cmd_parms *cmd, void *dummy, diff --git a/server/mpm/experimental/event/event_filters.c b/server/mpm/experimental/event/event_filters.c new file mode 100644 index 00000000000..0739e1ee81f --- /dev/null +++ b/server/mpm/experimental/event/event_filters.c @@ -0,0 +1,30 @@ +/* Copyright 2005 The Apache Software Foundation or its licensors, as + * applicable. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "apr_buckets.h" +#include "apr_errno.h" +#include "apr_support.h" +#include "httpd.h" +#include "http_connection.h" +#include "util_filter.h" + +apr_status_t ap_mpm_custom_write_filter(ap_filter_t *f, + apr_bucket_brigade *bb) +{ + /* write you own C-O-F here */ + return ap_core_output_filter(f, bb); +} +