]> granicus.if.org Git - apache/commitdiff
Merge r1235019, r1236122, r1240470:
authorStefan Fritsch <sf@apache.org>
Sat, 4 Feb 2012 10:04:59 +0000 (10:04 +0000)
committerStefan Fritsch <sf@apache.org>
Sat, 4 Feb 2012 10:04:59 +0000 (10:04 +0000)
    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
include/http_core.h
include/httpd.h
server/core.c
server/core_filters.c
server/mpm/winnt/child.c
server/mpm/winnt/mpm_winnt.c
server/mpm/winnt/mpm_winnt.h

index 319dc45ffce4130f4d697a3d997021d6249bb860..207fb059bb7b7437414996d5b8dc26116dfa084b 100644 (file)
  *                         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" */
 #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
index fc1b939aa50ea5ae50d2c650d61c64d2d993573e..8cbedc11c30778b0baa2001104b0246d15f01410 100644 (file)
@@ -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
index 90bbc1043bce46abf7098f2dcfa7a84505ebe96c..6ffdef2e173dec6d9b043945ce2e069d1c89883a 100644 (file)
@@ -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
index eb8147b84c313dbf251c94e1af8d2522e4c825ed..e96eaa3cd90c94e567dc74c0bc6e0c5a146475ff 100644 (file)
 
 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
index d094e662fc7b0c16d61145ea96d0bbb3752cc4e3..18a32dde221543d62245a9f89748a5a093259581 100644 (file)
@@ -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;
index ab4fddc3e79edde19f511f75405e3c97588647ab..2e42071fed4972638fefefdcb488362d923068ee 100644 (file)
@@ -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)
index cdf7cac640d1dc3f1240c45ad3e30a669b90b56d..4f6f8fe550ea7f75d9a435915a0406f8de30fdb6 100644 (file)
@@ -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) = {
index 62340d229293a2e2509a839e9b437f471b89e31b..f900fbf5e695a46372e0ffb13c1f5a31eb661b29 100644 (file)
@@ -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 */
 /** @} */