1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 * @brief functions pertaining to virtual host addresses
20 * (configuration and run-time)
24 #include "apr_strings.h"
27 #define APR_WANT_STRFUNC
30 #include "ap_config.h"
32 #include "http_config.h"
34 #include "http_vhost.h"
35 #include "http_protocol.h"
36 #include "http_core.h"
38 #if APR_HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
42 /* we know core's module_index is 0 */
43 #undef APLOG_MODULE_INDEX
44 #define APLOG_MODULE_INDEX AP_CORE_MODULE_INDEX
47 * After all the definitions there's an explanation of how it's all put
51 /* meta-list of name-vhosts. Each server_rec can be in possibly multiple
52 * lists of name-vhosts.
54 typedef struct name_chain name_chain;
57 server_addr_rec *sar; /* the record causing it to be in
58 * this chain (needed for port comparisons) */
59 server_rec *server; /* the server to use on a match */
62 /* meta-list of ip addresses. Each server_rec can be in possibly multiple
63 * hash chains since it can have multiple ips.
65 typedef struct ipaddr_chain ipaddr_chain;
68 server_addr_rec *sar; /* the record causing it to be in
69 * this chain (need for both ip addr and port
71 server_rec *server; /* the server to use if this matches */
72 name_chain *names; /* if non-NULL then a list of name-vhosts
73 * sharing this address */
74 name_chain *initialnames; /* no runtime use, temporary storage of first
78 /* This defines the size of the hash table used for hashing ip addresses
79 * of virtual hosts. It must be a power of two.
81 #ifndef IPHASH_TABLE_SIZE
82 #define IPHASH_TABLE_SIZE 256
85 /* A (n) bucket hash table, each entry has a pointer to a server rec and
86 * a pointer to the other entries in that bucket. Each individual address,
87 * even for virtualhosts with multiple addresses, has an entry in this hash
88 * table. There are extra buckets for _default_, and name-vhost entries.
90 * Note that after config time this is constant, so it is thread-safe.
92 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
94 /* dump out statistics about the hash function */
95 /* #define IPHASH_STATISTICS */
97 /* list of the _default_ servers */
98 static ipaddr_chain *default_list;
100 /* whether a config error was seen */
101 static int config_error = 0;
103 /* config check function */
104 static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
105 apr_pool_t *ptemp, server_rec *s);
110 * The ip address determines which chain in iphash_table is interesting, then
111 * a comparison is done down that chain to find the first ipaddr_chain whose
112 * sar matches the address:port pair.
114 * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
116 * Otherwise it's a name-vhost list, and the default is the server in the
117 * ipaddr_chain record. We tuck away the ipaddr_chain record in the
118 * conn_rec field vhost_lookup_data. Later on after the headers we get a
119 * second chance, and we use the name_chain to figure out what name-vhost
120 * matches the headers.
122 * If there was no ip address match in the iphash_table then do a lookup
123 * in the default_list.
125 * How it's put together ... well you should be able to figure that out
126 * from how it's used. Or something like that.
130 /* called at the beginning of the config */
131 AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
133 memset(iphash_table, 0, sizeof(iphash_table));
135 ap_hook_check_config(vhost_check_config, NULL, NULL, APR_HOOK_MIDDLE);
140 * Parses a host of the form <address>[:port]
141 * paddr is used to create a list in the order of input
142 * **paddr is the ->next pointer of the last entry (or s->addrs)
143 * *paddr is the variable used to keep track of **paddr between calls
144 * port is the default port to assume
146 static const char *get_addresses(apr_pool_t *p, const char *w_,
147 server_addr_rec ***paddr,
148 apr_port_t default_port)
150 apr_sockaddr_t *my_addr;
151 server_addr_rec *sar;
152 char *w, *host, *scope_id;
161 wlen = strlen(w_); /* wlen must be > 0 at this point */
162 w = apr_pstrmemdup(p, w_, wlen);
163 /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
165 if (w[wlen - 1] == '*') {
169 else if (w[wlen - 2] == ':') {
174 rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
175 /* If the string is "80", apr_parse_addr_port() will be happy and set
176 * host to NULL and port to 80, so watch out for that.
178 if (rv != APR_SUCCESS) {
179 return "The address or port is invalid";
182 return "Missing address for VirtualHost";
185 return "Scope ids are not supported";
187 if (!port && !wild_port) {
191 if (strcmp(host, "*") == 0 || strcasecmp(host, "_default_") == 0) {
192 rv = apr_sockaddr_info_get(&my_addr, NULL, APR_UNSPEC, port, 0, p);
194 return "Could not determine a wildcard address ('0.0.0.0') -- "
195 "check resolver configuration.";
199 rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
200 if (rv != APR_SUCCESS) {
201 ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, APLOGNO(00547)
202 "Could not resolve host name %s -- ignoring!", host);
207 /* Remember all addresses for the host */
210 sar = apr_pcalloc(p, sizeof(server_addr_rec));
213 sar->host_addr = my_addr;
214 sar->host_port = port;
215 sar->virthost = host;
216 my_addr = my_addr->next;
223 /* parse the <VirtualHost> addresses */
224 const char *ap_parse_vhost_addrs(apr_pool_t *p,
225 const char *hostname,
228 server_addr_rec **addrs;
231 /* start the list of addreses */
233 while (hostname[0]) {
234 err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
240 /* terminate the list */
243 if (s->addrs->host_port) {
244 /* override the default port which is inherited from main_server */
245 s->port = s->addrs->host_port;
252 AP_DECLARE_NONSTD(const char *)ap_set_name_virtual_host(cmd_parms *cmd,
256 static int warnonce = 0;
257 if (++warnonce == 1) {
258 ap_log_error(APLOG_MARK, APLOG_NOTICE|APLOG_STARTUP, APR_SUCCESS, NULL, APLOGNO(00548)
259 "NameVirtualHost has no effect and will be removed in the "
260 "next release %s:%d",
261 cmd->directive->filename,
262 cmd->directive->line_num);
269 /* hash table statistics, keep this in here for the beta period so
270 * we can find out if the hash function is ok
272 #ifdef IPHASH_STATISTICS
273 static int iphash_compare(const void *a, const void *b)
275 return (*(const int *) b - *(const int *) a);
279 static void dump_iphash_statistics(server_rec *main_s)
281 unsigned count[IPHASH_TABLE_SIZE];
285 char buf[HUGE_STRING_LEN];
289 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
291 for (src = iphash_table[i]; src; src = src->next) {
293 if (i < IPHASH_TABLE_SIZE) {
294 /* don't count the slop buckets in the total */
299 qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
300 p = buf + apr_snprintf(buf, sizeof(buf),
301 "iphash: total hashed = %u, avg chain = %u, "
302 "chain lengths (count x len):",
303 total, total / IPHASH_TABLE_SIZE);
305 for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
306 if (count[i - 1] != count[i]) {
307 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
308 total, count[i - 1]);
315 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
316 total, count[IPHASH_TABLE_SIZE - 1]);
317 ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
322 /* This hashing function is designed to get good distribution in the cases
323 * where the server is handling entire "networks" of servers. i.e. a
324 * whack of /24s. This is probably the most common configuration for
325 * ISPs with large virtual servers.
327 * NOTE: This function is symmetric (i.e. collapses all 4 octets
328 * into one), so machine byte order (big/little endianness) does not matter.
330 * Hash function provided by David Hankins.
332 static APR_INLINE unsigned hash_inaddr(unsigned key)
335 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
338 static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
342 /* The key is the last four bytes of the IP address.
343 * For IPv4, this is the entire address, as always.
344 * For IPv6, this is usually part of the MAC address.
346 key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
347 return hash_inaddr(key);
350 static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
351 server_rec *s, server_addr_rec *sar)
355 new = apr_palloc(p, sizeof(*new));
357 new->initialnames = NULL;
365 static name_chain *new_name_chain(apr_pool_t *p,
366 server_rec *s, server_addr_rec *sar)
370 new = apr_palloc(p, sizeof(*new));
378 static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
381 ipaddr_chain *trav = NULL;
382 ipaddr_chain *wild_match = NULL;
384 /* scan the hash table for an exact match first */
385 bucket = hash_addr(sa);
386 for (trav = iphash_table[bucket]; trav; trav = trav->next) {
387 server_addr_rec *sar = trav->sar;
388 apr_sockaddr_t *cur = sar->host_addr;
390 if (cur->port == sa->port) {
391 if (apr_sockaddr_equal(cur, sa)) {
395 if (wild_match == NULL && (cur->port == 0 || sa->port == 0)) {
396 if (apr_sockaddr_equal(cur, sa)) {
397 /* don't break, continue looking for an exact match */
405 static ipaddr_chain *find_default_server(apr_port_t port)
407 server_addr_rec *sar;
408 ipaddr_chain *trav = NULL;
409 ipaddr_chain *wild_match = NULL;
411 for (trav = default_list; trav; trav = trav->next) {
413 if (sar->host_port == port) {
417 if (wild_match == NULL && sar->host_port == 0) {
418 /* don't break, continue looking for an exact match */
426 #define IS_IN6_ANYADDR(ad) ((ad)->family == APR_INET6 \
427 && IN6_IS_ADDR_UNSPECIFIED(&(ad)->sa.sin6.sin6_addr))
429 #define IS_IN6_ANYADDR(ad) (0)
432 static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
436 char buf[MAX_STRING_LEN];
437 apr_sockaddr_t *ha = ic->sar->host_addr;
439 if ((ha->family == APR_INET && ha->sa.sin.sin_addr.s_addr == INADDR_ANY)
440 || IS_IN6_ANYADDR(ha)) {
441 len = apr_snprintf(buf, sizeof(buf), "*:%u",
445 len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
447 if (ic->sar->host_port == 0) {
450 if (ic->names == NULL) {
451 apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
452 ic->server->server_hostname,
453 ic->server->defn_name, ic->server->defn_line_number);
456 apr_file_printf(f, "%-22s is a NameVirtualHost\n"
457 "%8s default server %s (%s:%u)\n",
458 buf, "", ic->server->server_hostname,
459 ic->server->defn_name, ic->server->defn_line_number);
460 for (nc = ic->names; nc; nc = nc->next) {
461 if (nc->sar->host_port) {
462 apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
465 apr_file_printf(f, "%8s port * ", "");
467 apr_file_printf(f, "namevhost %s (%s:%u)\n",
468 nc->server->server_hostname,
469 nc->server->defn_name, nc->server->defn_line_number);
470 if (nc->server->names) {
471 apr_array_header_t *names = nc->server->names;
472 char **name = (char **)names->elts;
474 for (i = 0; i < names->nelts; ++i) {
476 apr_file_printf(f, "%16s alias %s\n", "", name[i]);
480 if (nc->server->wild_names) {
481 apr_array_header_t *names = nc->server->wild_names;
482 char **name = (char **)names->elts;
484 for (i = 0; i < names->nelts; ++i) {
486 apr_file_printf(f, "%16s wild alias %s\n", "", name[i]);
493 static void dump_vhost_config(apr_file_t *f)
498 apr_file_printf(f, "VirtualHost configuration:\n");
500 /* non-wildcard servers */
501 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
502 for (ic = iphash_table[i]; ic; ic = ic->next) {
507 /* wildcard servers */
508 for (ic = default_list; ic; ic = ic->next) {
515 * When a second or later virtual host maps to the same IP chain,
516 * add the relevant server names to the chain. Special care is taken
517 * to avoid adding ic->names until we're sure there are multiple VH'es.
519 static void add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
520 server_rec *s, server_addr_rec *sar,
524 name_chain *nc = new_name_chain(p, s, sar);
525 nc->next = ic->names;
527 /* iterating backwards, so each one we see becomes the current default server */
530 if (ic->names == NULL) {
531 if (ic->initialnames == NULL) {
532 /* first pass, set these names aside in case we see another VH.
533 * Until then, this looks like an IP-based VH to runtime.
535 ic->initialnames = nc;
538 /* second pass through this chain -- this really is an NVH, and we
539 * have two sets of names to link in.
541 nc->next = ic->initialnames;
543 ic->initialnames = NULL;
547 /* 3rd or more -- just keep stacking the names */
552 /* compile the tables and such we need to do the run-time vhost lookups */
553 AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
555 server_addr_rec *sar;
556 int has_default_vhost_addr;
559 ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
561 /* Main host first */
564 if (!s->server_hostname) {
565 s->server_hostname = ap_get_local_host(p);
568 /* initialize the tails */
569 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
570 iphash_table_tail[i] = &iphash_table[i];
573 /* The next things to go into the hash table are the virtual hosts
574 * themselves. They're listed off of main_s->next in the reverse
575 * order they occured in the config file, so we insert them at
576 * the iphash_table_tail but don't advance the tail.
579 for (s = main_s->next; s; s = s->next) {
580 server_addr_rec *sar_prev = NULL;
581 has_default_vhost_addr = 0;
582 for (sar = s->addrs; sar; sar = sar->next) {
584 char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
585 /* XXX: this treats 0.0.0.0 as a "default" server which matches no-exact-match for IPv6 */
586 if (!memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
587 ic = find_default_server(sar->host_port);
589 if (ic && sar->host_port == ic->sar->host_port) { /* we're a match for an existing "default server" */
590 if (!sar_prev || memcmp(sar_prev->host_addr->ipaddr_ptr, inaddr_any, sar_prev->host_addr->ipaddr_len)
591 || sar_prev->host_port != sar->host_port) {
592 add_name_vhost_config(p, main_s, s, sar, ic);
596 /* No default server, or we found a default server but
597 ** exactly one of us is a wildcard port, which means we want
598 ** two ip-based vhosts not an NVH with two names
600 ic = new_ipaddr_chain(p, s, sar);
601 ic->next = default_list;
603 add_name_vhost_config(p, main_s, s, sar, ic);
605 has_default_vhost_addr = 1;
608 /* see if it matches something we've already got */
609 ic = find_ipaddr(sar->host_addr);
611 if (!ic || sar->host_port != ic->sar->host_port) {
612 /* No matching server, or we found a matching server but
613 ** exactly one of us is a wildcard port, which means we want
614 ** two ip-based vhosts not an NVH with two names
616 unsigned bucket = hash_addr(sar->host_addr);
617 ic = new_ipaddr_chain(p, s, sar);
618 ic->next = *iphash_table_tail[bucket];
619 *iphash_table_tail[bucket] = ic;
621 add_name_vhost_config(p, main_s, s, sar, ic);
626 /* Ok now we want to set up a server_hostname if the user was
627 * silly enough to forget one.
628 * XXX: This is silly we should just crash and burn.
630 if (!s->server_hostname) {
631 if (has_default_vhost_addr) {
632 s->server_hostname = main_s->server_hostname;
634 else if (!s->addrs) {
635 /* what else can we do? at this point this vhost has
636 no configured name, probably because they used
637 DNS in the VirtualHost statement. It's disabled
638 anyhow by the host matching code. -djg */
640 apr_pstrdup(p, "bogus_host_without_forward_dns");
646 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
647 if (rv == APR_SUCCESS) {
648 s->server_hostname = apr_pstrdup(p, hostname);
651 /* again, what can we do? They didn't specify a
652 ServerName, and their DNS isn't working. -djg */
655 apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
656 ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s, APLOGNO(00549)
657 "Failed to resolve server name "
658 "for %s (check DNS) -- or specify an explicit "
662 apr_pstrdup(p, "bogus_host_without_reverse_dns");
668 #ifdef IPHASH_STATISTICS
669 dump_iphash_statistics(main_s);
671 if (ap_exists_config_define("DUMP_VHOSTS")) {
672 apr_file_t *thefile = NULL;
673 apr_file_open_stdout(&thefile, p);
674 dump_vhost_config(thefile);
678 static int vhost_check_config(apr_pool_t *p, apr_pool_t *plog,
679 apr_pool_t *ptemp, server_rec *s)
681 return config_error ? !OK : OK;
684 /*****************************************************************************
685 * run-time vhost matching functions
688 static apr_status_t fix_hostname_v6_literal(request_rec *r, char *host)
691 int double_colon = 0;
693 for (dst = host; *dst; dst++) {
694 if (apr_isxdigit(*dst)) {
695 if (apr_isupper(*dst)) {
696 *dst = apr_tolower(*dst);
699 else if (*dst == ':') {
700 if (*(dst + 1) == ':') {
705 else if (*(dst + 1) == '.') {
709 else if (*dst == '.') {
710 /* For IPv4-mapped IPv6 addresses like ::FFFF:129.144.52.38 */
711 if (*(dst + 1) == ':' || *(dst + 1) == '.')
721 static apr_status_t fix_hostname_non_v6(request_rec *r, char *host)
725 for (dst = host; *dst; dst++) {
726 if (apr_islower(*dst)) {
727 /* leave char unchanged */
729 else if (*dst == '.') {
730 if (*(dst + 1) == '.') {
734 else if (apr_isupper(*dst)) {
735 *dst = apr_tolower(*dst);
737 else if (*dst == '/' || *dst == '\\') {
741 /* strip trailing gubbins */
742 if (dst > host && dst[-1] == '.') {
749 * If strict mode ever becomes the default, this should be folded into
750 * fix_hostname_non_v6()
752 static apr_status_t strict_hostname_check(request_rec *r, char *host,
756 int is_dotted_decimal = 1, leading_zeroes = 0, dots = 0;
758 for (ch = host; *ch; ch++) {
759 if (!apr_isascii(*ch)) {
762 else if (apr_isalpha(*ch) || *ch == '-') {
763 is_dotted_decimal = 0;
765 else if (ch[0] == '.') {
767 if (ch[1] == '0' && apr_isdigit(ch[2]))
770 else if (!apr_isdigit(*ch)) {
771 /* also takes care of multiple Host headers by denying commas */
775 if (is_dotted_decimal) {
776 if (host[0] == '.' || (host[0] == '0' && apr_isdigit(host[1])))
778 if (leading_zeroes || dots != 3) {
784 /* The top-level domain must start with a letter (RFC 1123 2.1) */
785 while (ch > host && *ch != '.')
787 if (ch[0] == '.' && ch[1] != '\0' && !apr_isalpha(ch[1]))
793 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02415)
794 "[strict] Invalid host name '%s'%s%.6s",
795 host, *ch ? ", problem near: " : "", ch);
801 /* Lowercase and remove any trailing dot and/or :port from the hostname,
802 * and check that it is sane.
804 * In most configurations the exact syntax of the hostname isn't
805 * important so strict sanity checking isn't necessary. However, in
806 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
807 * the hostname is interpolated into the filename, we need to be sure
808 * that the interpolation doesn't expose parts of the filesystem.
809 * We don't do strict RFC 952 / RFC 1123 syntax checking in order
810 * to support iDNS and people who erroneously use underscores.
811 * Instead we just check for filesystem metacharacters: directory
812 * separators / and \ and sequences of more than one dot.
814 static int fix_hostname(request_rec *r, const char *host_header,
815 unsigned http_conformance)
818 char *host, *scope_id;
822 int is_v6literal = 0;
823 int strict = http_conformance & AP_HTTP_CONFORMANCE_STRICT;
824 int strict_logonly = http_conformance & AP_HTTP_CONFORMANCE_LOGONLY;
826 src = host_header ? host_header : r->hostname;
828 /* According to RFC 2616, Host header field CAN be blank */
833 /* apr_parse_addr_port will interpret a bare integer as a port
834 * which is incorrect in this context. So treat it separately.
836 for (c = src; apr_isdigit(*c); ++c);
841 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02416)
842 "[strict] purely numeric host names not allowed: %s",
852 rv = apr_parse_addr_port(&host, &scope_id, &port, src, r->pool);
853 if (rv != APR_SUCCESS || scope_id)
856 /* Don't throw the Host: header's port number away:
857 save it in parsed_uri -- ap_get_server_port() needs it! */
858 /* @@@ XXX there should be a better way to pass the port.
859 * Like r->hostname, there should be a r->portno
861 r->parsed_uri.port = port;
862 r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
864 if (host_header[0] == '[')
869 * Already parsed, surrounding [ ] (if IPv6 literal) and :port have
870 * already been removed.
872 host = apr_pstrdup(r->pool, r->hostname);
873 if (ap_strchr(host, ':') != NULL)
878 rv = fix_hostname_v6_literal(r, host);
881 rv = fix_hostname_non_v6(r, host);
882 if (strict && rv == APR_SUCCESS)
883 rv = strict_hostname_check(r, host, strict_logonly);
885 if (rv != APR_SUCCESS)
892 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(00550)
893 "Client sent malformed Host header: %s",
896 r->status = HTTP_BAD_REQUEST;
900 /* return 1 if host matches ServerName or ServerAliases */
901 static int matches_aliases(server_rec *s, const char *host)
904 apr_array_header_t *names;
906 /* match ServerName */
907 if (!strcasecmp(host, s->server_hostname)) {
911 /* search all the aliases from ServerAlias directive */
914 char **name = (char **) names->elts;
915 for (i = 0; i < names->nelts; ++i) {
916 if(!name[i]) continue;
917 if (!strcasecmp(host, name[i]))
921 names = s->wild_names;
923 char **name = (char **) names->elts;
924 for (i = 0; i < names->nelts; ++i) {
925 if(!name[i]) continue;
926 if (!ap_strcasecmp_match(host, name[i]))
934 /* Suppose a request came in on the same socket as this r, and included
935 * a header "Host: host:port", would it map to r->server? It's more
936 * than just that though. When we do the normal matches for each request
937 * we don't even bother considering Host: etc on non-namevirtualhosts,
938 * we just call it a match. But here we require the host:port to match
939 * the ServerName and/or ServerAliases.
941 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
945 server_addr_rec *sar;
949 /* search all the <VirtualHost> values */
950 /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
953 * NameVirtualHost 10.1.1.1
954 * <VirtualHost 10.1.1.1>
957 * <VirtualHost 10.1.1.1>
961 * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
962 * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
963 * it would really go to v1.
965 for (sar = s->addrs; sar; sar = sar->next) {
966 if ((sar->host_port == 0 || port == sar->host_port)
967 && !strcasecmp(host, sar->virthost)) {
972 /* the Port has to match now, because the rest don't have ports associated
974 if (port != s->port) {
978 return matches_aliases(s, host);
982 static void check_hostalias(request_rec *r)
985 * Even if the request has a Host: header containing a port we ignore
986 * that port. We always use the physical port of the socket. There
987 * are a few reasons for this:
989 * - the default of 80 or 443 for SSL is easier to handle this way
990 * - there is less of a possibility of a security problem
991 * - it simplifies the data structure
992 * - the client may have no idea that a proxy somewhere along the way
993 * translated the request to another ip:port
994 * - except for the addresses from the VirtualHost line, none of the other
995 * names we'll match have ports associated with them
997 const char *host = r->hostname;
1000 server_rec *virthost_s;
1007 port = r->connection->local_addr->port;
1009 /* Recall that the name_chain is a list of server_addr_recs, some of
1010 * whose ports may not match. Also each server may appear more than
1011 * once in the chain -- specifically, it will appear once for each
1012 * address from its VirtualHost line which matched. We only want to
1013 * do the full ServerName/ServerAlias comparisons once for each
1014 * server, fortunately we know that all the VirtualHost addresses for
1015 * a single server are adjacent to each other.
1018 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1019 server_addr_rec *sar;
1021 /* We only consider addresses on the name_chain which have a matching
1025 if (sar->host_port != 0 && port != sar->host_port) {
1031 /* If we still need to do ServerName and ServerAlias checks for this
1032 * server, do them now.
1035 /* does it match any ServerName or ServerAlias directive? */
1036 if (matches_aliases(s, host)) {
1042 /* Fallback: does it match the virthost from the sar? */
1043 if (!strcasecmp(host, sar->virthost)) {
1044 /* only the first match is used */
1045 if (virthost_s == NULL) {
1051 /* If ServerName and ServerAlias check failed, we end up here. If it
1052 * matches a VirtualHost, virthost_s is set. Use that as fallback
1062 /* s is the first matching server, we're done */
1067 static void check_serverpath(request_rec *r)
1074 port = r->connection->local_addr->port;
1077 * This is in conjunction with the ServerPath code in http_core, so we
1078 * get the right host attached to a non- Host-sending request.
1080 * See the comment in check_hostalias about how each vhost can be
1081 * listed multiple times.
1085 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
1086 /* We only consider addresses on the name_chain which have a matching
1089 if (src->sar->host_port != 0 && port != src->sar->host_port) {
1099 if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
1100 (s->path[s->pathlen - 1] == '/' ||
1101 r->uri[s->pathlen] == '/' ||
1102 r->uri[s->pathlen] == '\0')) {
1109 static APR_INLINE const char *construct_host_header(request_rec *r,
1112 struct iovec iov[5];
1113 apr_size_t nvec = 0;
1115 * We cannot use ap_get_server_name/port here, because we must
1116 * ignore UseCanonicalName/Port.
1119 iov[nvec].iov_base = "[";
1120 iov[nvec].iov_len = 1;
1123 iov[nvec].iov_base = (void *)r->hostname;
1124 iov[nvec].iov_len = strlen(r->hostname);
1127 iov[nvec].iov_base = "]";
1128 iov[nvec].iov_len = 1;
1131 if (r->parsed_uri.port_str) {
1132 iov[nvec].iov_base = ":";
1133 iov[nvec].iov_len = 1;
1135 iov[nvec].iov_base = r->parsed_uri.port_str;
1136 iov[nvec].iov_len = strlen(r->parsed_uri.port_str);
1139 return apr_pstrcatv(r->pool, iov, nvec, NULL);
1142 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
1144 core_server_config *conf = ap_get_core_module_config(r->server->module_config);
1145 const char *host_header = apr_table_get(r->headers_in, "Host");
1146 int is_v6literal = 0;
1147 int have_hostname_from_url = 0;
1151 * If there was a host part in the Request-URI, ignore the 'Host'
1154 have_hostname_from_url = 1;
1155 is_v6literal = fix_hostname(r, NULL, conf->http_conformance);
1157 else if (host_header != NULL) {
1158 is_v6literal = fix_hostname(r, host_header, conf->http_conformance);
1160 if (r->status != HTTP_OK)
1163 if (conf->http_conformance & AP_HTTP_CONFORMANCE_STRICT) {
1165 * If we have both hostname from an absoluteURI and a Host header,
1166 * we must ignore the Host header (RFC 2616 5.2).
1167 * To enforce this, we reset the Host header to the value from the
1170 if (have_hostname_from_url && host_header != NULL) {
1171 const char *info = "Would replace";
1172 const char *new = construct_host_header(r, is_v6literal);
1173 if (!(conf->http_conformance & AP_HTTP_CONFORMANCE_LOGONLY)) {
1174 apr_table_set(r->headers_in, "Host", r->hostname);
1177 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02417)
1178 "%s Host header '%s' with host from request uri: "
1179 "'%s'", info, host_header, new);
1183 /* check if we tucked away a name_chain */
1184 if (r->connection->vhost_lookup_data) {
1188 check_serverpath(r);
1193 * For every virtual host on this connection, call func_cb.
1195 AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
1196 ap_vhost_iterate_conn_cb func_cb,
1205 if (conn->vhost_lookup_data) {
1207 port = conn->local_addr->port;
1209 for (src = conn->vhost_lookup_data; src; src = src->next) {
1210 server_addr_rec *sar;
1212 /* We only consider addresses on the name_chain which have a
1216 if (sar->host_port != 0 && port != sar->host_port) {
1223 /* we've already done a callback for this vhost. */
1229 rv = func_cb(baton, conn, s);
1237 rv = func_cb(baton, conn, conn->base_server);
1243 /* Called for a new connection which has a known local_addr. Note that the
1244 * new connection is assumed to have conn->server == main server.
1246 AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1251 /* scan the hash table for an exact match first */
1252 trav = find_ipaddr(conn->local_addr);
1255 /* save the name_chain for later in case this is a name-vhost */
1256 conn->vhost_lookup_data = trav->names;
1257 conn->base_server = trav->server;
1261 /* maybe there's a default server or wildcard name-based vhost
1262 * matching this port
1264 port = conn->local_addr->port;
1266 trav = find_default_server(port);
1268 conn->vhost_lookup_data = trav->names;
1269 conn->base_server = trav->server;
1273 /* otherwise we're stuck with just the main server
1274 * and no name-based vhosts
1276 conn->vhost_lookup_data = NULL;