From 53e4a906db22ae4aef754973d6eb35993edd30b5 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Tue, 28 Dec 2010 11:21:56 +0000 Subject: [PATCH] prefer exact port matches in ip-based VH lookup over wildcards. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1053309 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 4 ++++ server/vhost.c | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 32613f3bd3..b6a5f34e1d 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.3.11 + *) core: When selecting an IP-based virtual host, favor an exact match for + the port over a wildcard (or omitted) port instead of favoring the one + that came first in the configuration file. [Eric Covener] + *) core: Overlapping virtual host address/port combinations now implicitly enable name-based virtual hosting for that address. The NameVirtualHost directive has no effect, and _default_ is interpreted the same as "*". diff --git a/server/vhost.c b/server/vhost.c index 02e24405bf..7763eddd5f 100644 --- a/server/vhost.c +++ b/server/vhost.c @@ -376,7 +376,8 @@ static name_chain *new_name_chain(apr_pool_t *p, static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa) { unsigned bucket; - ipaddr_chain *trav; + ipaddr_chain *trav = NULL; + ipaddr_chain *wild_match = NULL; /* scan the hash table for an exact match first */ bucket = hash_addr(sa); @@ -384,28 +385,39 @@ static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa) server_addr_rec *sar = trav->sar; apr_sockaddr_t *cur = sar->host_addr; - if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) { + if (cur->port == sa->port) { if (apr_sockaddr_equal(cur, sa)) { return trav; } } + if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) { + if (apr_sockaddr_equal(cur, sa)) { + /* don't break, continue looking for an exact match */ + wild_match = trav; + } + } } - return NULL; + return wild_match; } static ipaddr_chain *find_default_server(apr_port_t port) { server_addr_rec *sar; - ipaddr_chain *trav; + ipaddr_chain *trav = NULL; + ipaddr_chain *wild_match = NULL; for (trav = default_list; trav; trav = trav->next) { sar = trav->sar; - if (sar->host_port == 0 || sar->host_port == port) { + if (sar->host_port == port) { /* match! */ return trav; } + if (wild_match == NULL && sar->host_port == 0) { + /* don't break, continue looking for an exact match */ + wild_match = trav; + } } - return NULL; + return wild_match; } static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic) -- 2.40.0