From 60976e42a143a6272e72724b35211be2698a9ab0 Mon Sep 17 00:00:00 2001 From: Stefan Fritsch Date: Sat, 4 Feb 2012 10:04:59 +0000 Subject: [PATCH] Merge r1235019, r1236122, r1240470: Make the core input/output filter contexts private and provide a hook to insert a custom bucket, for use bye mpm_winnt and mod_ftp. This allows to add members to the context structs without breaking binary compatibility. This should be ABI back-compatible, so only a minor MMN bump. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1240478 13f79535-47bb-0310-9956-ffa450edef68 --- include/ap_mmn.h | 6 ++++- include/http_core.h | 27 ++++++++++++++++++++ include/httpd.h | 36 +++++++++------------------ server/core.c | 17 +++++++++++++ server/core_filters.c | 29 +++++++++++++--------- server/mpm/winnt/child.c | 48 ++++++++++++++---------------------- server/mpm/winnt/mpm_winnt.c | 2 ++ server/mpm/winnt/mpm_winnt.h | 4 +++ 8 files changed, 104 insertions(+), 65 deletions(-) diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 319dc45ffc..207fb059bb 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -385,6 +385,10 @@ * ap_proxy_table_unmerge(), proxy_lb_workers. * 20120109.0 (2.4.1-dev) Changes sizeof(overrides_t) in core config. * 20120109.1 (2.4.1-dev) remove sb_type in global_score. + * 20120109.2 (2.4.1-dev) Make core_output_filter_ctx_t and core_ctx_t + * private; + * move core_net rec definition to http_core.h; + * add insert_network_bucket hook, AP_DECLINED */ #define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */ @@ -392,7 +396,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20120109 #endif -#define MODULE_MAGIC_NUMBER_MINOR 1 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/include/http_core.h b/include/http_core.h index fc1b939aa5..8cbedc11c3 100644 --- a/include/http_core.h +++ b/include/http_core.h @@ -689,6 +689,33 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b); AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s); AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto); +typedef struct core_output_filter_ctx core_output_filter_ctx_t; +typedef struct core_filter_ctx core_ctx_t; + +typedef struct core_net_rec { + /** Connection to the client */ + apr_socket_t *client_socket; + + /** connection record */ + conn_rec *c; + + core_output_filter_ctx_t *out_ctx; + core_ctx_t *in_ctx; +} core_net_rec; + +/** + * Insert the network bucket into the core input filter's input brigade. + * This hook is intended for MPMs or protocol modules that need to do special + * socket setup. + * @param c The connection + * @param bb The brigade to insert the bucket into + * @param socket The socket to put into a bucket + * @return AP_DECLINED if the current function does not handle this connection, + * APR_SUCCESS or an error otherwise. + */ +AP_DECLARE_HOOK(apr_status_t, insert_network_bucket, + (conn_rec *c, apr_bucket_brigade *bb, apr_socket_t *socket)) + /* ---------------------------------------------------------------------- * * Runtime status/management diff --git a/include/httpd.h b/include/httpd.h index 90bbc1043b..6ffdef2e17 100644 --- a/include/httpd.h +++ b/include/httpd.h @@ -385,6 +385,18 @@ extern "C" { # define AP_CORE_DECLARE_NONSTD AP_DECLARE_NONSTD #endif +/** + * @defgroup APACHE_APR_STATUS_T HTTPD specific values of apr_status_t + * @{ + */ +#define AP_START_USERERR (APR_OS_START_USERERR + 2000) +#define AP_USERERR_LEN 1000 + +/** The function declines to handle the request */ +#define AP_DECLINED (AP_START_USERERR + 0) + +/** @} */ + /** * @brief The numeric version information is broken out into fields within this * structure. @@ -1270,30 +1282,6 @@ struct server_rec { void *context; }; -typedef struct core_output_filter_ctx { - apr_bucket_brigade *buffered_bb; - apr_bucket_brigade *tmp_flush_bb; - apr_pool_t *deferred_write_pool; - apr_size_t bytes_in; - apr_size_t bytes_written; -} core_output_filter_ctx_t; - -typedef struct core_filter_ctx { - apr_bucket_brigade *b; - apr_bucket_brigade *tmpbb; -} core_ctx_t; - -typedef struct core_net_rec { - /** Connection to the client */ - apr_socket_t *client_socket; - - /** connection record */ - conn_rec *c; - - core_output_filter_ctx_t *out_ctx; - core_ctx_t *in_ctx; -} core_net_rec; - /** * Get the context_document_root for a request. This is a generalization of * the document root, which is too limited in the presence of mappers like diff --git a/server/core.c b/server/core.c index eb8147b84c..e96eaa3cd9 100644 --- a/server/core.c +++ b/server/core.c @@ -82,12 +82,18 @@ APR_HOOK_STRUCT( APR_HOOK_LINK(get_mgmt_items) + APR_HOOK_LINK(insert_network_bucket) ) AP_IMPLEMENT_HOOK_RUN_ALL(int, get_mgmt_items, (apr_pool_t *p, const char *val, apr_hash_t *ht), (p, val, ht), OK, DECLINED) +AP_IMPLEMENT_HOOK_RUN_FIRST(apr_status_t, insert_network_bucket, + (conn_rec *c, apr_bucket_brigade *bb, + apr_socket_t *socket), + (c, bb, socket), AP_DECLINED) + /* Server core module... This module provides support for really basic * server operations, including options and commands which control the * operation of other modules. Consider this the bureaucracy module. @@ -4729,6 +4735,15 @@ AP_DECLARE(apr_uint32_t) ap_random_pick(apr_uint32_t min, apr_uint32_t max) return number; } +static apr_status_t core_insert_network_bucket(conn_rec *c, + apr_bucket_brigade *bb, + apr_socket_t *socket) +{ + apr_bucket *e = apr_bucket_socket_create(socket, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + return APR_SUCCESS; +} + static void core_dump_config(apr_pool_t *p, server_rec *s) { core_server_config *sconf = ap_get_core_module_config(s->module_config); @@ -4803,6 +4818,8 @@ static void register_hooks(apr_pool_t *p) APR_HOOK_MIDDLE); ap_hook_pre_mpm(ap_create_scoreboard, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_child_status(ap_core_child_status, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_network_bucket(core_insert_network_bucket, NULL, NULL, + APR_HOOK_REALLY_LAST); /* register the core's insert_filter hook and register core-provided * filters diff --git a/server/core_filters.c b/server/core_filters.c index d094e662fc..18a32dde22 100644 --- a/server/core_filters.c +++ b/server/core_filters.c @@ -78,11 +78,23 @@ do { \ #undef APLOG_MODULE_INDEX #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX +struct core_output_filter_ctx { + apr_bucket_brigade *buffered_bb; + apr_bucket_brigade *tmp_flush_bb; + apr_pool_t *deferred_write_pool; + apr_size_t bytes_written; +}; + +struct core_filter_ctx { + apr_bucket_brigade *b; + apr_bucket_brigade *tmpbb; +}; + + apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { - apr_bucket *e; apr_status_t rv; core_net_rec *net = f->ctx; core_ctx_t *ctx = net->in_ctx; @@ -105,18 +117,13 @@ apr_status_t ap_core_input_filter(ap_filter_t *f, apr_bucket_brigade *b, if (!ctx) { - /* - * Note that this code is never executed on Windows because the winnt - * MPM does the setup of net->in_ctx. - * XXX: This should be fixed. - */ - ctx = apr_pcalloc(f->c->pool, sizeof(*ctx)); + net->in_ctx = ctx = apr_palloc(f->c->pool, sizeof(*ctx)); ctx->b = apr_brigade_create(f->c->pool, f->c->bucket_alloc); - ctx->tmpbb = apr_brigade_create(ctx->b->p, ctx->b->bucket_alloc); + ctx->tmpbb = apr_brigade_create(f->c->pool, f->c->bucket_alloc); /* seed the brigade with the client socket. */ - e = apr_bucket_socket_create(net->client_socket, f->c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(ctx->b, e); - net->in_ctx = ctx; + rv = ap_run_insert_network_bucket(f->c, ctx->b, net->client_socket); + if (rv != APR_SUCCESS) + return rv; } else if (APR_BRIGADE_EMPTY(ctx->b)) { return APR_EOF; diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index ab4fddc3e7..2e42071fed 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -736,6 +736,23 @@ static winnt_conn_ctx_t *winnt_get_connection(winnt_conn_ctx_t *context) return context; } +apr_status_t winnt_insert_network_bucket(conn_rec *c, + apr_bucket_brigade *bb, + apr_socket_t *socket) +{ + apr_bucket *e; + winnt_conn_ctx_t *context = ap_get_module_config(c->conn_config, + &mpm_winnt_module); + if (context == NULL || (e = context->overlapped.Pointer) == NULL) + return AP_DECLINED; + + /* seed the brigade with AcceptEx read heap bucket */ + APR_BRIGADE_INSERT_HEAD(bb, e); + /* also seed the brigade with the client socket. */ + e = apr_bucket_socket_create(socket, c->bucket_alloc); + APR_BRIGADE_INSERT_TAIL(bb, e); + return APR_SUCCESS; +} /* * worker_main() @@ -810,36 +827,9 @@ static DWORD __stdcall worker_main(void *thread_num_val) { apr_bucket_free(e); } - else if (e) + else { - core_ctx_t *ctx; - core_net_rec *net; - ap_filter_t *filt; - - filt = c->input_filters; - while ((strcmp(filt->frec->name, "core_in") != 0) && filt->next) - filt = filt->next; - net = filt->ctx; - ctx = net->in_ctx; - - if (net->in_ctx) - ctx = net->in_ctx; - else - { - ctx = apr_pcalloc(c->pool, sizeof(*ctx)); - ctx->b = apr_brigade_create(c->pool, c->bucket_alloc); - ctx->tmpbb = apr_brigade_create(c->pool, c->bucket_alloc); - - /* seed the brigade with AcceptEx read heap bucket */ - e = context->overlapped.Pointer; - APR_BRIGADE_INSERT_HEAD(ctx->b, e); - - /* also seed the brigade with the client socket. */ - e = apr_bucket_socket_create(net->client_socket, - c->bucket_alloc); - APR_BRIGADE_INSERT_TAIL(ctx->b, e); - net->in_ctx = ctx; - } + ap_set_module_config(c->conn_config, &mpm_winnt_module, context); } if (!c->aborted) diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index cdf7cac640..4f6f8fe550 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -1758,6 +1758,8 @@ static void winnt_hooks(apr_pool_t *p) ap_hook_mpm(winnt_run, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_mpm_query(winnt_query, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_mpm_get_name(winnt_get_name, NULL, NULL, APR_HOOK_MIDDLE); + ap_hook_insert_network_bucket(winnt_insert_network_bucket, NULL, NULL, + APR_HOOK_MIDDLE); } AP_DECLARE_MODULE(mpm_winnt) = { diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h index 62340d2292..f900fbf5e6 100644 --- a/server/mpm/winnt/mpm_winnt.h +++ b/server/mpm/winnt/mpm_winnt.h @@ -67,6 +67,7 @@ void mpm_nt_eventlog_stderr_flush(void); /* From mpm_winnt.c: */ +extern module AP_MODULE_DECLARE_DATA mpm_winnt_module; extern int ap_threads_per_child; extern DWORD my_pid; @@ -92,6 +93,9 @@ void hold_console_open_on_error(void); /* From child.c: */ void child_main(apr_pool_t *pconf); +apr_status_t winnt_insert_network_bucket(conn_rec *c, + apr_bucket_brigade *bb, + apr_socket_t *socket); #endif /* APACHE_MPM_WINNT_H */ /** @} */ -- 2.40.0