]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* server/core.c: Add new directive: 'AcceptFilter'.
authorPaul Querna <pquerna@apache.org>
Fri, 20 May 2005 01:28:52 +0000 (01:28 +0000)
committerPaul Querna <pquerna@apache.org>
Fri, 20 May 2005 01:28:52 +0000 (01:28 +0000)
* server/core.c: Enable 'httpready' by default on systems that support it.  Use dataready filters for others.
* server/listen.c: Move bits that determined which accept filter is applied to core.c.
* server/listen.c: Add bits to find the correct accept filter based on the core's configuration.
* include/http_core.h: Add the accf_map table to the core_server_config structure

Tested on Linux using TCP_DEFER_ACCEPT.
Needs testing on FreeBSD to make sure that Accept Filters actually work.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/listen-protocol@171031 13f79535-47bb-0310-9956-ffa450edef68

include/http_core.h
server/core.c
server/listen.c

index 0578611a0becbcf28e96acf98857b7c4fb6cb422..6f202e778f768ddaeb9143220ec2064cf03bf8b9 100644 (file)
@@ -546,7 +546,8 @@ typedef struct {
     int redirect_limit; /* maximum number of internal redirects */
     int subreq_limit;   /* maximum nesting level of subrequests */
 
-    const char* protocol;
+    const char *protocol;
+    apr_table_t *accf_map;
 } core_server_config;
 
 /* for AddOutputFiltersByType in core.c */
index 01ccd5106af1bdd2361872b4767d09d1ac355027..8bea33fb054354eeb9e1a32d1430772291d45fd5 100644 (file)
@@ -461,6 +461,26 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s)
     conf->subreq_limit = 0;
 
     conf->protocol = NULL;
+    conf->accf_map = apr_table_make(a, 5);
+
+#ifdef APR_TCP_DEFER_ACCEPT
+    apr_table_set(conf->accf_map, "http", "data");
+    apr_table_set(conf->accf_map, "https", "data");
+#endif
+
+#if APR_HAS_SO_ACCEPTFILTER
+#ifndef ACCEPT_FILTER_NAME
+#define ACCEPT_FILTER_NAME "httpready"
+#ifdef __FreeBSD_version
+#if __FreeBSD_version < 411000 /* httpready broken before 4.1.1 */
+#undef ACCEPT_FILTER_NAME
+#define ACCEPT_FILTER_NAME "dataready"
+#endif
+#endif
+#endif 
+    apr_table_set(conf->accf_map, "http", ACCEPT_FILTER_NAME);
+    apr_table_set(conf->accf_map, "https", "dataready");
+#endif
 
     return (void *)conf;
 }
@@ -2187,6 +2207,27 @@ static const char *set_server_alias(cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
+static const char *set_accf_map(cmd_parms *cmd, void *dummy,
+                                const char *iproto, const char* iaccf)
+{
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+    core_server_config *conf = ap_get_module_config(cmd->server->module_config,
+                                                    &core_module);
+    char* proto;
+    char* accf;
+    if (err != NULL) {
+        return err;
+    }
+
+    proto = apr_pstrdup(cmd->pool, iproto);
+    ap_str_tolower(proto);
+    accf = apr_pstrdup(cmd->pool, iaccf);
+    ap_str_tolower(accf);
+    apr_table_set(conf->accf_map, proto, accf);
+
+    return NULL;
+}
+
 AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s) 
 {
     core_server_config *conf = ap_get_module_config(s->module_config,
@@ -3160,6 +3201,8 @@ AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO,
 
 AP_INIT_TAKE1("Protocol", set_protocol, NULL, RSRC_CONF,
   "Set the Protocol for httpd to use."),
+AP_INIT_TAKE2("AcceptFilter", set_accf_map, NULL, RSRC_CONF,
+  "Set the Accept Filter to use for a protocol"),
 AP_INIT_TAKE1("Port", ap_set_deprecated, NULL, RSRC_CONF,
   "Port was replaced with Listen in Apache 2.0"),
 AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL,
index fa4d209a1451deca70c8bbe86bff706155f12f57..05729ba497c22b737bd4cf295599a505b8b68155 100644 (file)
@@ -168,32 +168,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
     }
 #endif
 
-#if APR_HAS_SO_ACCEPTFILTER
-#ifndef ACCEPT_FILTER_NAME
-#define ACCEPT_FILTER_NAME "httpready"
-#ifdef __FreeBSD_version
-#if __FreeBSD_version < 411000 /* httpready broken before 4.1.1 */
-#undef ACCEPT_FILTER_NAME
-#define ACCEPT_FILTER_NAME "dataready"
-#endif
-#endif
-#endif
-    stat = apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, "");
-    if (stat != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(stat)) {
-        ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
-                      "Failed to enable the '%s' Accept Filter",
-                      ACCEPT_FILTER_NAME);
-    }
-#else
-#ifdef APR_TCP_DEFER_ACCEPT
-    stat = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 1);   
-    if (stat != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(stat)) {
-        ap_log_perror(APLOG_MARK, APLOG_WARNING, stat, p,
-                              "Failed to enable APR_TCP_DEFER_ACCEPT");
-    }
-#endif
-#endif
-
     server->sd = s;
     server->active = 1;
 
@@ -206,6 +180,61 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
     return APR_SUCCESS;
 }
 
+static const char* find_accf_name(server_rec *s, const char *proto)
+{
+    const char* accf;
+    core_server_config *conf = ap_get_module_config(s->module_config,
+                                                    &core_module);
+    if (!proto) {
+        return NULL;
+    }
+
+    accf = apr_table_get(conf->accf_map, proto);
+
+    if (accf && !strcmp("none", accf)) {
+        return NULL;
+    }
+
+    return accf;
+}
+
+static void ap_apply_accept_filter(apr_pool_t *p, ap_listen_rec *lis, 
+                                           server_rec *server)
+{
+    apr_socket_t *s = lis->sd;
+    const char *accf;
+    apr_status_t rv;
+    const char *proto;
+
+    proto = lis->protocol;
+
+    if (!proto) {
+        proto = ap_get_server_protocol(server);
+    }
+
+
+    accf = find_accf_name(server, proto);
+
+    if (accf) {
+#if APR_HAS_SO_ACCEPTFILTER
+        rv = apr_socket_accept_filter(s, ACCEPT_FILTER_NAME, "");
+        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
+            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p,
+                          "Failed to enable the '%s' Accept Filter",
+                          ACCEPT_FILTER_NAME);
+        }
+#else
+#ifdef APR_TCP_DEFER_ACCEPT
+        rv = apr_socket_opt_set(s, APR_TCP_DEFER_ACCEPT, 1);   
+        if (rv != APR_SUCCESS && !APR_STATUS_IS_ENOTIMPL(rv)) {
+            ap_log_perror(APLOG_MARK, APLOG_WARNING, rv, p,
+                              "Failed to enable APR_TCP_DEFER_ACCEPT");
+        }
+#endif
+#endif
+    }
+}
+
 static apr_status_t close_listeners_on_exec(void *v)
 {
     ap_listen_rec *lr;
@@ -459,27 +488,27 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
     ap_listen_rec *lr;
     int num_listeners = 0;
     const char* proto;
-    int nfound;
+    int found;
 
     for (ls = s; ls; ls = ls->next) {
         proto = ap_get_server_protocol(ls);
         if (!proto) {
-            nfound = 1;
+            found = 0;
             /* No protocol was set for this vhost, 
              * use the default for this listener. 
              */
-            for (addr = ls->addrs; addr && nfound; addr = addr->next) {
+            for (addr = ls->addrs; addr && !found; addr = addr->next) {
                 for (lr = ap_listeners; lr; lr = lr->next) {
                     if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
                         lr->bind_addr->port == addr->host_port) {
                         ap_set_server_protocol(ls, lr->protocol);
-                        nfound = 0;
+                        found = 1;
                         break;
                     }
                 }
             }
 
-            if (nfound) {
+            if (!found) {
                 /* TODO: set protocol defaults per-Port, eg 25=smtp */
                 ap_set_server_protocol(ls, "http");
             }
@@ -492,6 +521,20 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
 
     for (lr = ap_listeners; lr; lr = lr->next) {
         num_listeners++;
+        found = 0;
+        for (ls = s; ls && !found; ls = ls->next) {
+            for (addr = ls->addrs; addr && !found; addr = addr->next) {
+                if (apr_sockaddr_equal(lr->bind_addr, addr->host_addr) &&
+                    lr->bind_addr->port == addr->host_port) {
+                    found = 1;
+                    ap_apply_accept_filter(s->process->pool, lr, ls);
+                }
+            }
+        }
+
+        if (!found) {
+            ap_apply_accept_filter(s->process->pool, lr, s);
+        }
     }
 
     return num_listeners;