1
0
mirror of https://github.com/apache/httpd.git synced 2025-08-08 15:02:10 +03:00

Merge the listen-protocol sandbox branch to trunk.

I will be adding documentation for the new directives hopefully in the next day or so.

* server/core.c: Added 'Protocol' to the core module config
                 Added ap_{set,get}_server_protocol API.
                 Added new directive: 'AcceptFilter'.
                 Enable 'httpready' by default on systems that support it.  Use dataready filters for others.

* server/listen.c: Attempt to inherit protocols from Listener Records to Server configs.
                   The 'Listen' directive can now optionally take a protocol arg
                   Move bits that determined which accept filter is applied to core.c.
                   Added bits to find the correct accept filter based on the core's configuration.

* include/{ap_listen.h,http_core.h}: Add Protocol to respective structures.

* include/http_core.h: Add the accf_map table to the core_server_config structure

* include/ap_mmn.h: Minor MMN Bump for the new interfacces.

* modules/ssl/ssl_engine_init.c: Use the new protocol framework to enable mod_ssl for 'https' websites.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@190563 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Paul Querna
2005-06-14 09:21:18 +00:00
parent 13424c5f6e
commit 6a23d6ebeb
7 changed files with 232 additions and 38 deletions

View File

@@ -2,6 +2,14 @@ Changes with Apache 2.1.5
[Remove entries to the current 2.0 section below, when backported] [Remove entries to the current 2.0 section below, when backported]
*) mod_ssl: Setting the Protocol to 'https' can replace the use of the
'SSLEngine on' command. [Paul Querna]
*) core: Refactor the mapping of Accept Filters to Sockets. Add the
AcceptFilter and Protocol directives to aid in mapping filter types.
Extend the Listen directive to optionally take a protocol name.
[Paul Querna]
*) mod_disk_cache: Support storing multiple variations of one URL. PR 35211. *) mod_disk_cache: Support storing multiple variations of one URL. PR 35211.
[Paul Querna] [Paul Querna]

View File

@@ -53,7 +53,10 @@ struct ap_listen_rec {
* Is this socket currently active * Is this socket currently active
*/ */
int active; int active;
/* more stuff here, like which protocol is bound to the port */ /**
* The default protocol for this listening socket.
*/
const char* protocol;
}; };
/** /**
@@ -82,7 +85,8 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s);
* called. * called.
*/ */
AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, void *dummy, const char *arg);
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, const char *ips); AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
int argc, char *const argv[]);
AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy, AP_DECLARE_NONSTD(const char *) ap_set_send_buffer_size(cmd_parms *cmd, void *dummy,
const char *arg); const char *arg);
AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd, AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
@@ -92,8 +96,8 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
#define LISTEN_COMMANDS \ #define LISTEN_COMMANDS \
AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \ AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
"Maximum length of the queue of pending connections, as used by listen(2)"), \ "Maximum length of the queue of pending connections, as used by listen(2)"), \
AP_INIT_TAKE1("Listen", ap_set_listener, NULL, RSRC_CONF, \ AP_INIT_TAKE_ARGV("Listen", ap_set_listener, NULL, RSRC_CONF, \
"A port number or a numeric IP address and a port number"), \ "A port number or a numeric IP address and a port number, and an optional protocol"), \
AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \ AP_INIT_TAKE1("SendBufferSize", ap_set_send_buffer_size, NULL, RSRC_CONF, \
"Send buffer size in bytes"), \ "Send buffer size in bytes"), \
AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \ AP_INIT_TAKE1("ReceiveBufferSize", ap_set_receive_buffer_size, NULL, \

View File

@@ -95,6 +95,7 @@
* 20050305.0 (2.1.4-dev) added pid and generation fields to worker_score * 20050305.0 (2.1.4-dev) added pid and generation fields to worker_score
* 20050305.1 (2.1.5-dev) added ap_vhost_iterate_given_conn. * 20050305.1 (2.1.5-dev) added ap_vhost_iterate_given_conn.
* 20050305.2 (2.1.5-dev) added AP_INIT_TAKE_ARGV. * 20050305.2 (2.1.5-dev) added AP_INIT_TAKE_ARGV.
* 20050305.3 (2.1.5-dev) added Protocol Framework.
*/ */
#define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */ #define MODULE_MAGIC_COOKIE 0x41503230UL /* "AP20" */
@@ -102,7 +103,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR #ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20050305 #define MODULE_MAGIC_NUMBER_MAJOR 20050305
#endif #endif
#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */ #define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */
/** /**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a * Determine if the server's current MODULE_MAGIC_NUMBER is at least a

View File

@@ -548,6 +548,9 @@ typedef struct {
/* recursion backstopper */ /* recursion backstopper */
int redirect_limit; /* maximum number of internal redirects */ int redirect_limit; /* maximum number of internal redirects */
int subreq_limit; /* maximum nesting level of subrequests */ int subreq_limit; /* maximum nesting level of subrequests */
const char *protocol;
apr_table_t *accf_map;
} core_server_config; } core_server_config;
/* for AddOutputFiltersByType in core.c */ /* for AddOutputFiltersByType in core.c */
@@ -573,6 +576,8 @@ apr_status_t ap_core_output_filter(ap_filter_t *f, apr_bucket_brigade *b);
#endif /* CORE_PRIVATE */ #endif /* CORE_PRIVATE */
AP_DECLARE(const char*) ap_get_server_protocol(server_rec* s);
AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto);
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
* *

View File

@@ -207,6 +207,10 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
sc->vhost_id = ssl_util_vhostid(p, s); sc->vhost_id = ssl_util_vhostid(p, s);
sc->vhost_id_len = strlen(sc->vhost_id); sc->vhost_id_len = strlen(sc->vhost_id);
if (strcmp("https", ap_get_server_protocol(s)) == 0) {
sc->enabled = SSL_ENABLED_TRUE;
}
/* If sc->enabled is UNSET, then SSL is optional on this vhost */ /* If sc->enabled is UNSET, then SSL is optional on this vhost */
/* Fix up stuff that may not have been set */ /* Fix up stuff that may not have been set */
if (sc->enabled == SSL_ENABLED_UNSET) { if (sc->enabled == SSL_ENABLED_UNSET) {
@@ -879,7 +883,8 @@ static void ssl_init_server_certs(server_rec *s,
if (!(have_rsa || have_dsa)) { if (!(have_rsa || have_dsa)) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
"Oops, no RSA or DSA server certificate found?!"); "Oops, no RSA or DSA server certificate found "
"for '%s:%d'?!", s->server_hostname, s->port);
ssl_die(); ssl_die();
} }

View File

@@ -460,6 +460,28 @@ static void *create_core_server_config(apr_pool_t *a, server_rec *s)
conf->redirect_limit = 0; /* 0 == unset */ conf->redirect_limit = 0; /* 0 == unset */
conf->subreq_limit = 0; 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; return (void *)conf;
} }
@@ -480,6 +502,10 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
conf->ap_document_root = base->ap_document_root; conf->ap_document_root = base->ap_document_root;
} }
if (!conf->protocol) {
conf->protocol = base->protocol;
}
conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir); conf->sec_dir = apr_array_append(p, base->sec_dir, virt->sec_dir);
conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url); conf->sec_url = apr_array_append(p, base->sec_url, virt->sec_url);
@@ -490,7 +516,6 @@ static void *merge_core_server_configs(apr_pool_t *p, void *basev, void *virtv)
conf->subreq_limit = virt->subreq_limit conf->subreq_limit = virt->subreq_limit
? virt->subreq_limit ? virt->subreq_limit
: base->subreq_limit; : base->subreq_limit;
return conf; return conf;
} }
@@ -2182,6 +2207,60 @@ static const char *set_server_alias(cmd_parms *cmd, void *dummy,
return NULL; 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,
&core_module);
return conf->protocol;
}
AP_DECLARE(void) ap_set_server_protocol(server_rec* s, const char* proto)
{
core_server_config *conf = ap_get_module_config(s->module_config,
&core_module);
conf->protocol = proto;
}
static const char *set_protocol(cmd_parms *cmd, void *dummy,
const char *arg)
{
const char *err = ap_check_cmd_context(cmd, NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT);
core_server_config *conf = ap_get_module_config(cmd->server->module_config,
&core_module);
char* proto;
if (err != NULL) {
return err;
}
proto = apr_pstrdup(cmd->pool, arg);
ap_str_tolower(proto);
conf->protocol = proto;
return NULL;
}
static const char *set_server_string_slot(cmd_parms *cmd, void *dummy, static const char *set_server_string_slot(cmd_parms *cmd, void *dummy,
const char *arg) const char *arg)
{ {
@@ -3120,6 +3199,10 @@ AP_INIT_TAKE1("EnableSendfile", set_enable_sendfile, NULL, OR_FILEINFO,
/* Old server config file commands */ /* Old server config file commands */
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, AP_INIT_TAKE1("Port", ap_set_deprecated, NULL, RSRC_CONF,
"Port was replaced with Listen in Apache 2.0"), "Port was replaced with Listen in Apache 2.0"),
AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL, AP_INIT_TAKE1("HostnameLookups", set_hostname_lookups, NULL,

View File

@@ -24,6 +24,7 @@
#include "ap_config.h" #include "ap_config.h"
#include "httpd.h" #include "httpd.h"
#include "http_config.h" #include "http_config.h"
#include "http_core.h"
#include "ap_listen.h" #include "ap_listen.h"
#include "http_log.h" #include "http_log.h"
#include "mpm.h" #include "mpm.h"
@@ -167,32 +168,6 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
} }
#endif #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->sd = s;
server->active = 1; server->active = 1;
@@ -205,6 +180,62 @@ static apr_status_t make_sock(apr_pool_t *p, ap_listen_rec *server)
return APR_SUCCESS; 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, apr_pstrdup(p, accf),
apr_pstrdup(p,""));
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",
accf);
}
#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) static apr_status_t close_listeners_on_exec(void *v)
{ {
ap_listen_rec *lr; ap_listen_rec *lr;
@@ -218,7 +249,8 @@ static apr_status_t close_listeners_on_exec(void *v)
} }
static const char *alloc_listener(process_rec *process, char *addr, apr_port_t port) static const char *alloc_listener(process_rec *process, char *addr,
apr_port_t port, const char* proto)
{ {
ap_listen_rec **walk, *last; ap_listen_rec **walk, *last;
apr_status_t status; apr_status_t status;
@@ -279,6 +311,7 @@ static const char *alloc_listener(process_rec *process, char *addr, apr_port_t p
new->active = 0; new->active = 0;
new->next = 0; new->next = 0;
new->bind_addr = sa; new->bind_addr = sa;
new->protocol = apr_pstrdup(process->pool, proto);
/* Go to the next sockaddr. */ /* Go to the next sockaddr. */
sa = sa->next; sa = sa->next;
@@ -451,8 +484,37 @@ static int open_listeners(apr_pool_t *pool)
AP_DECLARE(int) ap_setup_listeners(server_rec *s) AP_DECLARE(int) ap_setup_listeners(server_rec *s)
{ {
server_rec *ls;
server_addr_rec *addr;
ap_listen_rec *lr; ap_listen_rec *lr;
int num_listeners = 0; int num_listeners = 0;
const char* proto;
int found;
for (ls = s; ls; ls = ls->next) {
proto = ap_get_server_protocol(ls);
if (!proto) {
found = 0;
/* No protocol was set for this vhost,
* use the default for this listener.
*/
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);
found = 1;
break;
}
}
}
if (!found) {
/* TODO: set protocol defaults per-Port, eg 25=smtp */
ap_set_server_protocol(ls, "http");
}
}
}
if (open_listeners(s->process->pool)) { if (open_listeners(s->process->pool)) {
return 0; return 0;
@@ -460,6 +522,20 @@ AP_DECLARE(int) ap_setup_listeners(server_rec *s)
for (lr = ap_listeners; lr; lr = lr->next) { for (lr = ap_listeners; lr; lr = lr->next) {
num_listeners++; 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; return num_listeners;
@@ -474,9 +550,9 @@ AP_DECLARE(void) ap_listen_pre_config(void)
AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy, AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
const char *ips) int argc, char *const argv[])
{ {
char *host, *scope_id; char *host, *scope_id, *proto;
apr_port_t port; apr_port_t port;
apr_status_t rv; apr_status_t rv;
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
@@ -485,7 +561,11 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
return err; return err;
} }
rv = apr_parse_addr_port(&host, &scope_id, &port, ips, cmd->pool); if (argc < 1 || argc > 2) {
return "Listen requires 1 or 2 arguments.";
}
rv = apr_parse_addr_port(&host, &scope_id, &port, argv[0], cmd->pool);
if (rv != APR_SUCCESS) { if (rv != APR_SUCCESS) {
return "Invalid address or port"; return "Invalid address or port";
} }
@@ -503,7 +583,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_listener(cmd_parms *cmd, void *dummy,
return "Port must be specified"; return "Port must be specified";
} }
return alloc_listener(cmd->server->process, host, port); if (argc != 2) {
proto = "http";
}
else {
proto = apr_pstrdup(cmd->pool, argv[1]);
ap_str_tolower(proto);
}
return alloc_listener(cmd->server->process, host, port, proto);
} }
AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd, AP_DECLARE_NONSTD(const char *) ap_set_listenbacklog(cmd_parms *cmd,