1 /* ====================================================================
2 * The Apache Software License, Version 1.1
4 * Copyright (c) 2000 The Apache Software Foundation. All rights
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * ====================================================================
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
54 * Portions of this software are based upon public domain software
55 * originally written at the National Center for Supercomputing Applications,
56 * University of Illinois, Urbana-Champaign.
60 * http_vhost.c: functions pertaining to virtual host addresses
61 * (configuration and run-time)
65 #include "ap_config.h"
67 #include "http_config.h"
69 #include "http_vhost.h"
70 #include "http_protocol.h"
71 #include "http_core.h"
72 #include "apr_strings.h"
74 #ifdef HAVE_ARPA_INET_H
75 #include <arpa/inet.h>
77 #ifdef HAVE_NETINET_IN_H
78 #include <netinet/in.h>
80 #ifdef HAVE_SYS_SOCKET_H
81 #include <sys/socket.h>
91 * After all the definitions there's an explanation of how it's all put
95 /* meta-list of name-vhosts. Each server_rec can be in possibly multiple
96 * lists of name-vhosts.
98 typedef struct name_chain name_chain;
101 server_addr_rec *sar; /* the record causing it to be in
102 * this chain (needed for port comparisons) */
103 server_rec *server; /* the server to use on a match */
106 /* meta-list of ip addresses. Each server_rec can be in possibly multiple
107 * hash chains since it can have multiple ips.
109 typedef struct ipaddr_chain ipaddr_chain;
110 struct ipaddr_chain {
112 server_addr_rec *sar; /* the record causing it to be in
113 * this chain (need for both ip addr and port
115 server_rec *server; /* the server to use if this matches */
116 name_chain *names; /* if non-NULL then a list of name-vhosts
117 * sharing this address */
120 /* This defines the size of the hash apr_table_t used for hashing ip addresses
121 * of virtual hosts. It must be a power of two.
123 #ifndef IPHASH_TABLE_SIZE
124 #define IPHASH_TABLE_SIZE 256
127 /* A (n) bucket hash table, each entry has a pointer to a server rec and
128 * a pointer to the other entries in that bucket. Each individual address,
129 * even for virtualhosts with multiple addresses, has an entry in this hash
130 * table. There are extra buckets for _default_, and name-vhost entries.
132 * Note that after config time this is constant, so it is thread-safe.
134 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
136 /* dump out statistics about the hash function */
137 /* #define IPHASH_STATISTICS */
139 /* list of the _default_ servers */
140 static ipaddr_chain *default_list;
142 /* list of the NameVirtualHost addresses */
143 static server_addr_rec *name_vhost_list;
144 static server_addr_rec **name_vhost_list_tail;
149 * The ip address determines which chain in iphash_table is interesting, then
150 * a comparison is done down that chain to find the first ipaddr_chain whose
151 * sar matches the address:port pair.
153 * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
155 * Otherwise it's a name-vhost list, and the default is the server in the
156 * ipaddr_chain record. We tuck away the ipaddr_chain record in the
157 * conn_rec field vhost_lookup_data. Later on after the headers we get a
158 * second chance, and we use the name_chain to figure out what name-vhost
159 * matches the headers.
161 * If there was no ip address match in the iphash_table then do a lookup
162 * in the default_list.
164 * How it's put together ... well you should be able to figure that out
165 * from how it's used. Or something like that.
169 /* called at the beginning of the config */
170 void ap_init_vhost_config(apr_pool_t *p)
172 memset(iphash_table, 0, sizeof(iphash_table));
174 name_vhost_list = NULL;
175 name_vhost_list_tail = &name_vhost_list;
180 * Parses a host of the form <address>[:port]
181 * paddr is used to create a list in the order of input
182 * **paddr is the ->next pointer of the last entry (or s->addrs)
183 * *paddr is the variable used to keep track of **paddr between calls
184 * port is the default port to assume
186 static const char *get_addresses(apr_pool_t *p, const char *w_,
187 server_addr_rec ***paddr,
188 apr_port_t default_port)
190 apr_sockaddr_t *my_addr;
191 server_addr_rec *sar;
192 char *w, *host, *scope_id;
201 w = apr_pstrdup(p, w_);
202 /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
204 if (wlen > 2 && w[wlen - 1] == '*' && w[wlen - 2] == ':') {
211 rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
212 if (rv != APR_SUCCESS) {
213 return "The address or port is invalid";
216 return "Scope ids are not supported";
218 if (!port && !wild_port) {
222 if (strcasecmp(host, "_default_") == 0
223 || strcmp(host, "255.255.255.255") == 0) {
224 rv = apr_getaddrinfo(&my_addr, NULL, APR_INET, port, 0, p);
225 ap_assert(rv == APR_SUCCESS); /* must be bug or out of storage */
226 my_addr->sa.sin.sin_addr.s_addr = DEFAULT_VHOST_ADDR;
228 rv = apr_getaddrinfo(&my_addr, host, APR_UNSPEC, port, 0, p);
229 if (rv != APR_SUCCESS) {
230 ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
231 "Cannot resolve host name %s --- ignoring!", host);
236 /* XXX Gotta go through *all* addresses for the host name!
237 * Fix apr_getaddrinfo() to save them! */
239 sar = apr_pcalloc(p, sizeof(server_addr_rec));
242 sar->host_addr = my_addr;
243 sar->host_port = port;
244 sar->virthost = host;
249 /* parse the <VirtualHost> addresses */
250 const char *ap_parse_vhost_addrs(apr_pool_t *p, const char *hostname, server_rec *s)
252 server_addr_rec **addrs;
255 /* start the list of addreses */
257 while (hostname[0]) {
258 err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
264 /* terminate the list */
267 if (s->addrs->host_port) {
268 /* override the default port which is inherited from main_server */
269 s->port = s->addrs->host_port;
276 const char *ap_set_name_virtual_host (cmd_parms *cmd, void *dummy,
279 /* use whatever port the main server has at this point */
280 return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
285 /* hash apr_table_t statistics, keep this in here for the beta period so
286 * we can find out if the hash function is ok
288 #ifdef IPHASH_STATISTICS
289 static int iphash_compare(const void *a, const void *b)
291 return (*(const int *) b - *(const int *) a);
295 static void dump_iphash_statistics(server_rec *main_s)
297 unsigned count[IPHASH_TABLE_SIZE];
301 char buf[HUGE_STRING_LEN];
305 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
307 for (src = iphash_table[i]; src; src = src->next) {
309 if (i < IPHASH_TABLE_SIZE) {
310 /* don't count the slop buckets in the total */
315 qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
316 p = buf + apr_snprintf(buf, sizeof(buf),
317 "iphash: total hashed = %u, avg chain = %u, "
318 "chain lengths (count x len):",
319 total, total / IPHASH_TABLE_SIZE);
321 for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
322 if (count[i - 1] != count[i]) {
323 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
324 total, count[i - 1]);
331 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
332 total, count[IPHASH_TABLE_SIZE - 1]);
333 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, main_s, buf);
338 /* This hashing function is designed to get good distribution in the cases
339 * where the server is handling entire "networks" of servers. i.e. a
340 * whack of /24s. This is probably the most common configuration for
341 * ISPs with large virtual servers.
343 * NOTE: This function is symmetric (i.e. collapses all 4 octets
344 * into one), so machine byte order (big/little endianness) does not matter.
346 * Hash function provided by David Hankins.
348 static apr_inline unsigned hash_inaddr(unsigned key)
351 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
354 static apr_inline unsigned hash_addr(struct apr_sockaddr_t *sa)
358 /* The key is the last four bytes of the IP address.
359 * For IPv4, this is the entire address, as always.
360 * For IPv6, this is usually part of the MAC address.
362 key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
363 return hash_inaddr(key);
366 static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
367 server_rec *s, server_addr_rec *sar)
371 new = apr_palloc(p, sizeof(*new));
380 static name_chain *new_name_chain(apr_pool_t *p, server_rec *s, server_addr_rec *sar)
384 new = apr_palloc(p, sizeof(*new));
392 static apr_inline ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
397 /* scan the hash apr_table_t for an exact match first */
398 bucket = hash_addr(sa);
399 for (trav = iphash_table[bucket]; trav; trav = trav->next) {
400 server_addr_rec *sar = trav->sar;
401 apr_sockaddr_t *cur = sar->host_addr;
403 if (cur->sa.sin.sin_port == 0 ||
404 sa->sa.sin.sin_port == 0 ||
405 cur->sa.sin.sin_port == sa->sa.sin.sin_port) {
406 if (cur->ipaddr_len == sa->ipaddr_len &&
407 !memcmp(cur->ipaddr_ptr,
418 static ipaddr_chain *find_default_server(apr_port_t port)
420 server_addr_rec *sar;
423 for (trav = default_list; trav; trav = trav->next) {
425 if (sar->host_port == 0 || sar->host_port == port) {
433 static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
437 char buf[MAX_STRING_LEN];
438 apr_sockaddr_t *ha = ic->sar->host_addr;
440 if (ha->sa.sin.sin_family == APR_INET &&
441 ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) {
442 len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
445 else if (ha->sa.sin.sin_family == APR_INET &&
446 ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
447 len = apr_snprintf(buf, sizeof(buf), "*:%u",
451 len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
453 if (ic->sar->host_port == 0) {
456 if (ic->names == NULL) {
457 apr_fprintf(f, "%-22s %s (%s:%u)\n", buf, ic->server->server_hostname,
458 ic->server->defn_name, ic->server->defn_line_number);
461 apr_fprintf(f, "%-22s is a NameVirtualHost\n"
462 "%22s default server %s (%s:%u)\n",
463 buf, "", ic->server->server_hostname,
464 ic->server->defn_name, ic->server->defn_line_number);
465 for (nc = ic->names; nc; nc = nc->next) {
466 if (nc->sar->host_port) {
467 apr_fprintf(f, "%22s port %u ", "", nc->sar->host_port);
470 apr_fprintf(f, "%22s port * ", "");
472 apr_fprintf(f, "namevhost %s (%s:%u)\n", nc->server->server_hostname,
473 nc->server->defn_name, nc->server->defn_line_number);
477 static void dump_vhost_config(apr_file_t *f)
482 apr_fprintf(f, "VirtualHost configuration:\n");
483 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
484 for (ic = iphash_table[i]; ic; ic = ic->next) {
489 apr_fprintf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
490 for (ic = default_list; ic; ic = ic->next) {
497 * Two helper functions for ap_fini_vhost_config()
499 static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s, server_rec *s,
500 server_addr_rec *sar, ipaddr_chain *ic)
502 /* the first time we encounter a NameVirtualHost address
503 * ic->server will be NULL, on subsequent encounters
504 * ic->names will be non-NULL.
506 if (ic->names || ic->server == NULL) {
507 name_chain *nc = new_name_chain(p, s, sar);
508 nc->next = ic->names;
511 if (sar->host_port != ic->sar->host_port) {
512 /* one of the two is a * port, the other isn't */
513 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, main_s,
514 "VirtualHost %s:%u -- mixing * "
515 "ports and non-* ports with "
516 "a NameVirtualHost address is not supported,"
517 " proceeding with undefined results",
518 sar->virthost, sar->host_port);
523 /* IP-based vhosts are handled by the caller */
528 static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
531 ipaddr_chain *ic = *pic;
533 if (ic->server == NULL) {
534 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
535 "NameVirtualHost %s:%u has no VirtualHosts",
536 ic->sar->virthost, ic->sar->host_port);
539 else if (ic->names == NULL) {
540 /* if server != NULL and names == NULL then we're done
541 * looking at NameVirtualHosts
551 /* compile the tables and such we need to do the run-time vhost lookups */
552 void ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
554 server_addr_rec *sar;
555 int has_default_vhost_addr;
558 ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
560 /* terminate the name_vhost list */
561 *name_vhost_list_tail = NULL;
563 /* Main host first */
566 if (!s->server_hostname) {
567 s->server_hostname = ap_get_local_host(p);
570 /* initialize the tails */
571 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
572 iphash_table_tail[i] = &iphash_table[i];
575 /* The first things to go into the hash apr_table_t are the NameVirtualHosts
576 * Since name_vhost_list is in the same order that the directives
577 * occured in the config file, we'll copy it in that order.
579 for (sar = name_vhost_list; sar; sar = sar->next) {
580 unsigned bucket = hash_addr(sar->host_addr);
581 ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
583 if (sar->host_addr->sa.sin.sin_addr.s_addr != INADDR_ANY) {
584 *iphash_table_tail[bucket] = ic;
585 iphash_table_tail[bucket] = &ic->next;
588 /* A wildcard NameVirtualHost goes on the default_list so
589 * that it can catch incoming requests on any address.
591 ic->next = default_list;
594 /* Notice that what we've done is insert an ipaddr_chain with
595 * both server and names NULL. This fact is used to spot name-
596 * based vhosts in add_name_vhost_config().
600 /* The next things to go into the hash apr_table_t are the virtual hosts
601 * themselves. They're listed off of main_s->next in the reverse
602 * order they occured in the config file, so we insert them at
603 * the iphash_table_tail but don't advance the tail.
606 for (s = main_s->next; s; s = s->next) {
607 has_default_vhost_addr = 0;
608 for (sar = s->addrs; sar; sar = sar->next) {
611 if (sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR
612 || sar->host_addr->sa.sin.sin_addr.s_addr == INADDR_ANY) {
613 ic = find_default_server(sar->host_port);
614 if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
615 if (ic && ic->sar->host_port != 0) {
616 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING,
617 0, main_s, "_default_ VirtualHost overlap on port %u,"
618 " the first has precedence", sar->host_port);
620 ic = new_ipaddr_chain(p, s, sar);
621 ic->next = default_list;
624 has_default_vhost_addr = 1;
627 /* see if it matches something we've already got */
628 ic = find_ipaddr(sar->host_addr);
631 unsigned bucket = hash_addr(sar->host_addr);
633 ic = new_ipaddr_chain(p, s, sar);
634 ic->next = *iphash_table_tail[bucket];
635 *iphash_table_tail[bucket] = ic;
637 else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
638 ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_WARNING, 0, main_s,
639 "VirtualHost %s:%u overlaps with "
640 "VirtualHost %s:%u, the first has precedence, "
641 "perhaps you need a NameVirtualHost directive",
642 sar->virthost, sar->host_port,
643 ic->sar->virthost, ic->sar->host_port);
650 /* Ok now we want to set up a server_hostname if the user was
651 * silly enough to forget one.
652 * XXX: This is silly we should just crash and burn.
654 if (!s->server_hostname) {
655 if (has_default_vhost_addr) {
656 s->server_hostname = main_s->server_hostname;
658 else if (!s->addrs) {
659 /* what else can we do? at this point this vhost has
660 no configured name, probably because they used
661 DNS in the VirtualHost statement. It's disabled
662 anyhow by the host matching code. -djg */
664 apr_pstrdup(p, "bogus_host_without_forward_dns");
670 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
671 if (rv == APR_SUCCESS) {
672 s->server_hostname = apr_pstrdup(p, hostname);
675 /* again, what can we do? They didn't specify a
676 ServerName, and their DNS isn't working. -djg */
679 apr_get_ipaddr(&ipaddr_str, s->addrs->host_addr);
680 ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
681 "Failed to resolve server name "
682 "for %s (check DNS) -- or specify an explicit "
686 apr_pstrdup(p, "bogus_host_without_reverse_dns");
692 /* now go through and delete any NameVirtualHosts that didn't have any
693 * hosts associated with them. Lamers.
695 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
696 remove_unused_name_vhosts(main_s, &iphash_table[i]);
698 remove_unused_name_vhosts(main_s, &default_list);
700 #ifdef IPHASH_STATISTICS
701 dump_iphash_statistics(main_s);
703 if (getenv("DUMP_VHOSTS")) {
704 apr_file_t *thefile = NULL;
705 apr_open_stderr(&thefile, p);
706 dump_vhost_config(thefile);
711 /*****************************************************************************
712 * run-time vhost matching functions
715 /* Lowercase and remove any trailing dot and/or :port from the hostname,
716 * and check that it is sane.
718 * In most configurations the exact syntax of the hostname isn't
719 * important so strict sanity checking isn't necessary. However, in
720 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
721 * the hostname is interpolated into the filename, we need to be sure
722 * that the interpolation doesn't expose parts of the filesystem.
723 * We don't do strict RFC 952 / RFC 1123 syntax checking in order
724 * to support iDNS and people who erroneously use underscores.
725 * Instead we just check for filesystem metacharacters: directory
726 * separators / and \ and sequences of more than one dot.
728 static void fix_hostname(request_rec *r)
730 char *host, *scope_id;
735 rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
736 if (rv != APR_SUCCESS || scope_id) {
740 /* if the hostname is an IPv6 numeric address string, it was validated
741 * already; otherwise, further validation is needed
743 if (r->hostname[0] != '[') {
746 if (!apr_isalnum(*dst) && *dst != '-') {
760 /* strip trailing gubbins */
761 if (dst > host && dst[-1] == '.') {
769 r->status = HTTP_BAD_REQUEST;
770 ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
771 "Client sent malformed Host header");
776 /* return 1 if host matches ServerName or ServerAliases */
777 static int matches_aliases(server_rec *s, const char *host)
780 apr_array_header_t *names;
782 /* match ServerName */
783 if (!strcasecmp(host, s->server_hostname)) {
787 /* search all the aliases from ServerAlias directive */
790 char **name = (char **) names->elts;
791 for (i = 0; i < names->nelts; ++i) {
792 if(!name[i]) continue;
793 if (!strcasecmp(host, name[i]))
797 names = s->wild_names;
799 char **name = (char **) names->elts;
800 for (i = 0; i < names->nelts; ++i) {
801 if(!name[i]) continue;
802 if (!ap_strcasecmp_match(host, name[i]))
810 /* Suppose a request came in on the same socket as this r, and included
811 * a header "Host: host:port", would it map to r->server? It's more
812 * than just that though. When we do the normal matches for each request
813 * we don't even bother considering Host: etc on non-namevirtualhosts,
814 * we just call it a match. But here we require the host:port to match
815 * the ServerName and/or ServerAliases.
817 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
821 server_addr_rec *sar;
825 /* search all the <VirtualHost> values */
826 /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
829 * NameVirtualHost 10.1.1.1
830 * <VirtualHost 10.1.1.1>
833 * <VirtualHost 10.1.1.1>
837 * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
838 * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
839 * it would really go to v1.
841 for (sar = s->addrs; sar; sar = sar->next) {
842 if ((sar->host_port == 0 || port == sar->host_port)
843 && !strcasecmp(host, sar->virthost)) {
848 /* the Port has to match now, because the rest don't have ports associated
850 if (port != s->port) {
854 return matches_aliases(s, host);
858 static void check_hostalias(request_rec *r)
861 * Even if the request has a Host: header containing a port we ignore
862 * that port. We always use the physical port of the socket. There
863 * are a few reasons for this:
865 * - the default of 80 or 443 for SSL is easier to handle this way
866 * - there is less of a possibility of a security problem
867 * - it simplifies the data structure
868 * - the client may have no idea that a proxy somewhere along the way
869 * translated the request to another ip:port
870 * - except for the addresses from the VirtualHost line, none of the other
871 * names we'll match have ports associated with them
873 const char *host = r->hostname;
878 apr_sockaddr_t *localsa;
881 apr_get_sockaddr(&localsa, APR_LOCAL, r->connection->client_socket);
882 apr_get_port(&port, localsa);
884 /* Recall that the name_chain is a list of server_addr_recs, some of
885 * whose ports may not match. Also each server may appear more than
886 * once in the chain -- specifically, it will appear once for each
887 * address from its VirtualHost line which matched. We only want to
888 * do the full ServerName/ServerAlias comparisons once for each
889 * server, fortunately we know that all the VirtualHost addresses for
890 * a single server are adjacent to each other.
893 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
894 server_addr_rec *sar;
896 /* We only consider addresses on the name_chain which have a matching
900 if (sar->host_port != 0 && port != sar->host_port) {
906 /* does it match the virthost from the sar? */
907 if (!strcasecmp(host, sar->virthost)) {
912 /* we've already done ServerName and ServerAlias checks for this
919 if (matches_aliases(s, host)) {
926 /* s is the first matching server, we're done */
931 static void check_serverpath(request_rec *r)
937 apr_sockaddr_t *localsa;
939 apr_get_sockaddr(&localsa, APR_LOCAL, r->connection->client_socket);
940 apr_get_port(&port, localsa);
943 * This is in conjunction with the ServerPath code in http_core, so we
944 * get the right host attached to a non- Host-sending request.
946 * See the comment in check_hostalias about how each vhost can be
947 * listed multiple times.
951 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
952 /* We only consider addresses on the name_chain which have a matching
955 if (src->sar->host_port != 0 && port != src->sar->host_port) {
965 if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
966 (s->path[s->pathlen - 1] == '/' ||
967 r->uri[s->pathlen] == '/' ||
968 r->uri[s->pathlen] == '\0')) {
976 void ap_update_vhost_from_headers(request_rec *r)
978 /* must set this for HTTP/1.1 support */
979 if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
981 if (r->status != HTTP_OK)
984 /* check if we tucked away a name_chain */
985 if (r->connection->vhost_lookup_data) {
994 /* Called for a new connection which has a known local_addr. Note that the
995 * new connection is assumed to have conn->server == main server.
997 void ap_update_vhost_given_ip(conn_rec *conn)
1002 /* scan the hash apr_table_t for an exact match first */
1003 trav = find_ipaddr(conn->local_addr);
1005 /* save the name_chain for later in case this is a name-vhost */
1006 conn->vhost_lookup_data = trav->names;
1007 conn->base_server = trav->server;
1011 /* maybe there's a default server or wildcard name-based vhost
1012 * matching this port
1014 apr_get_port(&port, conn->local_addr);
1015 trav = find_default_server(port);
1017 conn->vhost_lookup_data = trav->names;
1018 conn->base_server = trav->server;
1022 /* otherwise we're stuck with just the main server
1023 * and no name-based vhosts
1025 conn->vhost_lookup_data = NULL;