summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Querna <pquerna@apache.org>2005-05-20 01:28:52 +0000
committerPaul Querna <pquerna@apache.org>2005-05-20 01:28:52 +0000
commit3208f2102852ada2a3e19d9bab7f629ef1aaab03 (patch)
treee533d8fff844f1cfe6a907973243dad31783178e
parent79836e7aa8908b57640d549b0b89b0de194caa6f (diff)
downloadhttpd-3208f2102852ada2a3e19d9bab7f629ef1aaab03.tar.gz
* server/core.c: Add new directive: 'AcceptFilter'.
* 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
-rw-r--r--include/http_core.h3
-rw-r--r--server/core.c43
-rw-r--r--server/listen.c105
3 files changed, 119 insertions, 32 deletions
diff --git a/include/http_core.h b/include/http_core.h
index 0578611a0b..6f202e778f 100644
--- a/include/http_core.h
+++ b/include/http_core.h
@@ -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 */
diff --git a/server/core.c b/server/core.c
index 01ccd5106a..8bea33fb05 100644
--- a/server/core.c
+++ b/server/core.c
@@ -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,
diff --git a/server/listen.c b/server/listen.c
index fa4d209a14..05729ba497 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -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;