Moved apache code into a folder to help prepare for packaging where we dont want...
[httpd-crcsyncproxy.git] / apache / server / vhost.c
blob6ed6cfea835eda1472e827395141bf7a0bb6eb1a
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.
17 /**
18 * @file vhost.c
19 * @brief functions pertaining to virtual host addresses
20 * (configuration and run-time)
23 #include "apr.h"
24 #include "apr_strings.h"
25 #include "apr_lib.h"
27 #define APR_WANT_STRFUNC
28 #include "apr_want.h"
30 #include "ap_config.h"
31 #include "httpd.h"
32 #include "http_config.h"
33 #include "http_log.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>
40 #endif
43 * After all the definitions there's an explanation of how it's all put
44 * together.
47 /* meta-list of name-vhosts. Each server_rec can be in possibly multiple
48 * lists of name-vhosts.
50 typedef struct name_chain name_chain;
51 struct name_chain {
52 name_chain *next;
53 server_addr_rec *sar; /* the record causing it to be in
54 * this chain (needed for port comparisons) */
55 server_rec *server; /* the server to use on a match */
58 /* meta-list of ip addresses. Each server_rec can be in possibly multiple
59 * hash chains since it can have multiple ips.
61 typedef struct ipaddr_chain ipaddr_chain;
62 struct ipaddr_chain {
63 ipaddr_chain *next;
64 server_addr_rec *sar; /* the record causing it to be in
65 * this chain (need for both ip addr and port
66 * comparisons) */
67 server_rec *server; /* the server to use if this matches */
68 name_chain *names; /* if non-NULL then a list of name-vhosts
69 * sharing this address */
72 /* This defines the size of the hash table used for hashing ip addresses
73 * of virtual hosts. It must be a power of two.
75 #ifndef IPHASH_TABLE_SIZE
76 #define IPHASH_TABLE_SIZE 256
77 #endif
79 /* A (n) bucket hash table, each entry has a pointer to a server rec and
80 * a pointer to the other entries in that bucket. Each individual address,
81 * even for virtualhosts with multiple addresses, has an entry in this hash
82 * table. There are extra buckets for _default_, and name-vhost entries.
84 * Note that after config time this is constant, so it is thread-safe.
86 static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
88 /* dump out statistics about the hash function */
89 /* #define IPHASH_STATISTICS */
91 /* list of the _default_ servers */
92 static ipaddr_chain *default_list;
94 /* list of the NameVirtualHost addresses */
95 static server_addr_rec *name_vhost_list;
96 static server_addr_rec **name_vhost_list_tail;
99 * How it's used:
101 * The ip address determines which chain in iphash_table is interesting, then
102 * a comparison is done down that chain to find the first ipaddr_chain whose
103 * sar matches the address:port pair.
105 * If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
107 * Otherwise it's a name-vhost list, and the default is the server in the
108 * ipaddr_chain record. We tuck away the ipaddr_chain record in the
109 * conn_rec field vhost_lookup_data. Later on after the headers we get a
110 * second chance, and we use the name_chain to figure out what name-vhost
111 * matches the headers.
113 * If there was no ip address match in the iphash_table then do a lookup
114 * in the default_list.
116 * How it's put together ... well you should be able to figure that out
117 * from how it's used. Or something like that.
121 /* called at the beginning of the config */
122 AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
124 memset(iphash_table, 0, sizeof(iphash_table));
125 default_list = NULL;
126 name_vhost_list = NULL;
127 name_vhost_list_tail = &name_vhost_list;
132 * Parses a host of the form <address>[:port]
133 * paddr is used to create a list in the order of input
134 * **paddr is the ->next pointer of the last entry (or s->addrs)
135 * *paddr is the variable used to keep track of **paddr between calls
136 * port is the default port to assume
138 static const char *get_addresses(apr_pool_t *p, const char *w_,
139 server_addr_rec ***paddr,
140 apr_port_t default_port)
142 apr_sockaddr_t *my_addr;
143 server_addr_rec *sar;
144 char *w, *host, *scope_id;
145 int wild_port;
146 apr_size_t wlen;
147 apr_port_t port;
148 apr_status_t rv;
150 if (*w_ == '\0')
151 return NULL;
153 w = apr_pstrdup(p, w_);
154 /* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
155 wlen = strlen(w); /* wlen must be > 0 at this point */
156 wild_port = 0;
157 if (w[wlen - 1] == '*') {
158 if (wlen < 2) {
159 wild_port = 1;
161 else if (w[wlen - 2] == ':') {
162 w[wlen - 2] = '\0';
163 wild_port = 1;
166 rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
167 /* If the string is "80", apr_parse_addr_port() will be happy and set
168 * host to NULL and port to 80, so watch out for that.
170 if (rv != APR_SUCCESS) {
171 return "The address or port is invalid";
173 if (!host) {
174 return "Missing address for VirtualHost";
176 if (scope_id) {
177 return "Scope ids are not supported";
179 if (!port && !wild_port) {
180 port = default_port;
183 if (strcmp(host, "*") == 0) {
184 rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p);
185 if (rv) {
186 return "Could not resolve address '0.0.0.0' -- "
187 "check resolver configuration.";
190 else if (strcasecmp(host, "_default_") == 0
191 || strcmp(host, "255.255.255.255") == 0) {
192 rv = apr_sockaddr_info_get(&my_addr, "255.255.255.255", APR_INET, port, 0, p);
193 if (rv) {
194 return "Could not resolve address '255.255.255.255' -- "
195 "check resolver configuration.";
198 else {
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,
202 "Could not resolve host name %s -- ignoring!", host);
203 return NULL;
207 /* Remember all addresses for the host */
209 do {
210 sar = apr_pcalloc(p, sizeof(server_addr_rec));
211 **paddr = sar;
212 *paddr = &sar->next;
213 sar->host_addr = my_addr;
214 sar->host_port = port;
215 sar->virthost = host;
216 my_addr = my_addr->next;
217 } while (my_addr);
219 return NULL;
223 /* parse the <VirtualHost> addresses */
224 const char *ap_parse_vhost_addrs(apr_pool_t *p,
225 const char *hostname,
226 server_rec *s)
228 server_addr_rec **addrs;
229 const char *err;
231 /* start the list of addreses */
232 addrs = &s->addrs;
233 while (hostname[0]) {
234 err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
235 if (err) {
236 *addrs = NULL;
237 return err;
240 /* terminate the list */
241 *addrs = NULL;
242 if (s->addrs) {
243 if (s->addrs->host_port) {
244 /* override the default port which is inherited from main_server */
245 s->port = s->addrs->host_port;
248 return NULL;
252 const char *ap_set_name_virtual_host(cmd_parms *cmd, void *dummy,
253 const char *arg)
255 /* use whatever port the main server has at this point */
256 return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
257 cmd->server->port);
261 /* hash table statistics, keep this in here for the beta period so
262 * we can find out if the hash function is ok
264 #ifdef IPHASH_STATISTICS
265 static int iphash_compare(const void *a, const void *b)
267 return (*(const int *) b - *(const int *) a);
271 static void dump_iphash_statistics(server_rec *main_s)
273 unsigned count[IPHASH_TABLE_SIZE];
274 int i;
275 ipaddr_chain *src;
276 unsigned total;
277 char buf[HUGE_STRING_LEN];
278 char *p;
280 total = 0;
281 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
282 count[i] = 0;
283 for (src = iphash_table[i]; src; src = src->next) {
284 ++count[i];
285 if (i < IPHASH_TABLE_SIZE) {
286 /* don't count the slop buckets in the total */
287 ++total;
291 qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
292 p = buf + apr_snprintf(buf, sizeof(buf),
293 "iphash: total hashed = %u, avg chain = %u, "
294 "chain lengths (count x len):",
295 total, total / IPHASH_TABLE_SIZE);
296 total = 1;
297 for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
298 if (count[i - 1] != count[i]) {
299 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
300 total, count[i - 1]);
301 total = 1;
303 else {
304 ++total;
307 p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
308 total, count[IPHASH_TABLE_SIZE - 1]);
309 ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
311 #endif
314 /* This hashing function is designed to get good distribution in the cases
315 * where the server is handling entire "networks" of servers. i.e. a
316 * whack of /24s. This is probably the most common configuration for
317 * ISPs with large virtual servers.
319 * NOTE: This function is symmetric (i.e. collapses all 4 octets
320 * into one), so machine byte order (big/little endianness) does not matter.
322 * Hash function provided by David Hankins.
324 static APR_INLINE unsigned hash_inaddr(unsigned key)
326 key ^= (key >> 16);
327 return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
330 static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
332 unsigned key;
334 /* The key is the last four bytes of the IP address.
335 * For IPv4, this is the entire address, as always.
336 * For IPv6, this is usually part of the MAC address.
338 key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
339 return hash_inaddr(key);
342 static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
343 server_rec *s, server_addr_rec *sar)
345 ipaddr_chain *new;
347 new = apr_palloc(p, sizeof(*new));
348 new->names = NULL;
349 new->server = s;
350 new->sar = sar;
351 new->next = NULL;
352 return new;
356 static name_chain *new_name_chain(apr_pool_t *p,
357 server_rec *s, server_addr_rec *sar)
359 name_chain *new;
361 new = apr_palloc(p, sizeof(*new));
362 new->server = s;
363 new->sar = sar;
364 new->next = NULL;
365 return new;
369 static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
371 unsigned bucket;
372 ipaddr_chain *trav;
374 /* scan the hash table for an exact match first */
375 bucket = hash_addr(sa);
376 for (trav = iphash_table[bucket]; trav; trav = trav->next) {
377 server_addr_rec *sar = trav->sar;
378 apr_sockaddr_t *cur = sar->host_addr;
380 if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) {
381 if (apr_sockaddr_equal(cur, sa)) {
382 return trav;
386 return NULL;
389 static ipaddr_chain *find_default_server(apr_port_t port)
391 server_addr_rec *sar;
392 ipaddr_chain *trav;
394 for (trav = default_list; trav; trav = trav->next) {
395 sar = trav->sar;
396 if (sar->host_port == 0 || sar->host_port == port) {
397 /* match! */
398 return trav;
401 return NULL;
404 static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
406 name_chain *nc;
407 int len;
408 char buf[MAX_STRING_LEN];
409 apr_sockaddr_t *ha = ic->sar->host_addr;
411 if (ha->family == APR_INET &&
412 ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) {
413 len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
414 ic->sar->host_port);
416 else if (ha->family == APR_INET &&
417 ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
418 len = apr_snprintf(buf, sizeof(buf), "*:%u",
419 ic->sar->host_port);
421 else {
422 len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
424 if (ic->sar->host_port == 0) {
425 buf[len-1] = '*';
427 if (ic->names == NULL) {
428 apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
429 ic->server->server_hostname,
430 ic->server->defn_name, ic->server->defn_line_number);
431 return;
433 apr_file_printf(f, "%-22s is a NameVirtualHost\n"
434 "%8s default server %s (%s:%u)\n",
435 buf, "", ic->server->server_hostname,
436 ic->server->defn_name, ic->server->defn_line_number);
437 for (nc = ic->names; nc; nc = nc->next) {
438 if (nc->sar->host_port) {
439 apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
441 else {
442 apr_file_printf(f, "%8s port * ", "");
444 apr_file_printf(f, "namevhost %s (%s:%u)\n",
445 nc->server->server_hostname,
446 nc->server->defn_name, nc->server->defn_line_number);
450 static void dump_vhost_config(apr_file_t *f)
452 ipaddr_chain *ic;
453 int i;
455 apr_file_printf(f, "VirtualHost configuration:\n");
456 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
457 for (ic = iphash_table[i]; ic; ic = ic->next) {
458 dump_a_vhost(f, ic);
461 if (default_list) {
462 apr_file_printf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
463 for (ic = default_list; ic; ic = ic->next) {
464 dump_a_vhost(f, ic);
470 * Two helper functions for ap_fini_vhost_config()
472 static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
473 server_rec *s, server_addr_rec *sar,
474 ipaddr_chain *ic)
476 /* the first time we encounter a NameVirtualHost address
477 * ic->server will be NULL, on subsequent encounters
478 * ic->names will be non-NULL.
480 if (ic->names || ic->server == NULL) {
481 name_chain *nc = new_name_chain(p, s, sar);
482 nc->next = ic->names;
483 ic->names = nc;
484 ic->server = s;
485 if (sar->host_port != ic->sar->host_port) {
486 /* one of the two is a * port, the other isn't */
487 ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_s,
488 "VirtualHost %s:%u -- mixing * "
489 "ports and non-* ports with "
490 "a NameVirtualHost address is not supported,"
491 " proceeding with undefined results",
492 sar->virthost, sar->host_port);
494 return 1;
496 else {
497 /* IP-based vhosts are handled by the caller */
498 return 0;
502 static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
504 while (*pic) {
505 ipaddr_chain *ic = *pic;
507 if (ic->server == NULL) {
508 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_s,
509 "NameVirtualHost %s:%u has no VirtualHosts",
510 ic->sar->virthost, ic->sar->host_port);
511 *pic = ic->next;
513 else {
514 pic = &ic->next;
519 /* compile the tables and such we need to do the run-time vhost lookups */
520 AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
522 server_addr_rec *sar;
523 int has_default_vhost_addr;
524 server_rec *s;
525 int i;
526 ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
528 /* terminate the name_vhost list */
529 *name_vhost_list_tail = NULL;
531 /* Main host first */
532 s = main_s;
534 if (!s->server_hostname) {
535 s->server_hostname = ap_get_local_host(p);
538 /* initialize the tails */
539 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
540 iphash_table_tail[i] = &iphash_table[i];
543 /* The first things to go into the hash table are the NameVirtualHosts
544 * Since name_vhost_list is in the same order that the directives
545 * occured in the config file, we'll copy it in that order.
547 for (sar = name_vhost_list; sar; sar = sar->next) {
548 char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
549 unsigned bucket = hash_addr(sar->host_addr);
550 ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
552 if (memcmp(sar->host_addr->ipaddr_ptr, inaddr_any,
553 sar->host_addr->ipaddr_len)) { /* not IN[6]ADDR_ANY */
554 *iphash_table_tail[bucket] = ic;
555 iphash_table_tail[bucket] = &ic->next;
557 else {
558 /* A wildcard NameVirtualHost goes on the default_list so
559 * that it can catch incoming requests on any address.
561 ic->next = default_list;
562 default_list = ic;
564 /* Notice that what we've done is insert an ipaddr_chain with
565 * both server and names NULL. This fact is used to spot name-
566 * based vhosts in add_name_vhost_config().
570 /* The next things to go into the hash table are the virtual hosts
571 * themselves. They're listed off of main_s->next in the reverse
572 * order they occured in the config file, so we insert them at
573 * the iphash_table_tail but don't advance the tail.
576 for (s = main_s->next; s; s = s->next) {
577 has_default_vhost_addr = 0;
578 for (sar = s->addrs; sar; sar = sar->next) {
579 ipaddr_chain *ic;
580 char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
582 if ((sar->host_addr->family == AF_INET &&
583 sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR)
584 || !memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
585 ic = find_default_server(sar->host_port);
586 if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
587 if (ic && ic->sar->host_port != 0) {
588 ap_log_error(APLOG_MARK, APLOG_WARNING,
589 0, main_s, "_default_ VirtualHost "
590 "overlap on port %u, the first has "
591 "precedence", sar->host_port);
593 ic = new_ipaddr_chain(p, s, sar);
594 ic->next = default_list;
595 default_list = ic;
597 has_default_vhost_addr = 1;
599 else {
600 /* see if it matches something we've already got */
601 ic = find_ipaddr(sar->host_addr);
603 if (!ic) {
604 unsigned bucket = hash_addr(sar->host_addr);
606 ic = new_ipaddr_chain(p, s, sar);
607 ic->next = *iphash_table_tail[bucket];
608 *iphash_table_tail[bucket] = ic;
610 else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
611 ap_log_error(APLOG_MARK, APLOG_WARNING,
612 0, main_s, "VirtualHost %s:%u overlaps "
613 "with VirtualHost %s:%u, the first has "
614 "precedence, perhaps you need a "
615 "NameVirtualHost directive",
616 sar->virthost, sar->host_port,
617 ic->sar->virthost, ic->sar->host_port);
618 ic->sar = sar;
619 ic->server = s;
624 /* Ok now we want to set up a server_hostname if the user was
625 * silly enough to forget one.
626 * XXX: This is silly we should just crash and burn.
628 if (!s->server_hostname) {
629 if (has_default_vhost_addr) {
630 s->server_hostname = main_s->server_hostname;
632 else if (!s->addrs) {
633 /* what else can we do? at this point this vhost has
634 no configured name, probably because they used
635 DNS in the VirtualHost statement. It's disabled
636 anyhow by the host matching code. -djg */
637 s->server_hostname =
638 apr_pstrdup(p, "bogus_host_without_forward_dns");
640 else {
641 apr_status_t rv;
642 char *hostname;
644 rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
645 if (rv == APR_SUCCESS) {
646 s->server_hostname = apr_pstrdup(p, hostname);
648 else {
649 /* again, what can we do? They didn't specify a
650 ServerName, and their DNS isn't working. -djg */
651 char *ipaddr_str;
653 apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
654 ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
655 "Failed to resolve server name "
656 "for %s (check DNS) -- or specify an explicit "
657 "ServerName",
658 ipaddr_str);
659 s->server_hostname =
660 apr_pstrdup(p, "bogus_host_without_reverse_dns");
666 /* now go through and delete any NameVirtualHosts that didn't have any
667 * hosts associated with them. Lamers.
669 for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
670 remove_unused_name_vhosts(main_s, &iphash_table[i]);
672 remove_unused_name_vhosts(main_s, &default_list);
674 #ifdef IPHASH_STATISTICS
675 dump_iphash_statistics(main_s);
676 #endif
677 if (ap_exists_config_define("DUMP_VHOSTS")) {
678 apr_file_t *thefile = NULL;
679 apr_file_open_stdout(&thefile, p);
680 dump_vhost_config(thefile);
685 /*****************************************************************************
686 * run-time vhost matching functions
689 /* Lowercase and remove any trailing dot and/or :port from the hostname,
690 * and check that it is sane.
692 * In most configurations the exact syntax of the hostname isn't
693 * important so strict sanity checking isn't necessary. However, in
694 * mass hosting setups (using mod_vhost_alias or mod_rewrite) where
695 * the hostname is interpolated into the filename, we need to be sure
696 * that the interpolation doesn't expose parts of the filesystem.
697 * We don't do strict RFC 952 / RFC 1123 syntax checking in order
698 * to support iDNS and people who erroneously use underscores.
699 * Instead we just check for filesystem metacharacters: directory
700 * separators / and \ and sequences of more than one dot.
702 static void fix_hostname(request_rec *r)
704 char *host, *scope_id;
705 char *dst;
706 apr_port_t port;
707 apr_status_t rv;
709 /* According to RFC 2616, Host header field CAN be blank. */
710 if (!*r->hostname) {
711 return;
714 rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
715 if (rv != APR_SUCCESS || scope_id) {
716 goto bad;
719 if (!host && port) {
720 /* silly looking host ("Host: 123") but that isn't our job
721 * here to judge; apr_parse_addr_port() would think we had a port
722 * but no address
724 host = apr_itoa(r->pool, (int)port);
726 else if (port) {
727 /* Don't throw the Host: header's port number away:
728 save it in parsed_uri -- ap_get_server_port() needs it! */
729 /* @@@ XXX there should be a better way to pass the port.
730 * Like r->hostname, there should be a r->portno
732 r->parsed_uri.port = port;
733 r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
736 /* if the hostname is an IPv6 numeric address string, it was validated
737 * already; otherwise, further validation is needed
739 if (r->hostname[0] != '[') {
740 for (dst = host; *dst; dst++) {
741 if (apr_islower(*dst)) {
742 /* leave char unchanged */
744 else if (*dst == '.') {
745 if (*(dst + 1) == '.') {
746 goto bad;
749 else if (apr_isupper(*dst)) {
750 *dst = apr_tolower(*dst);
752 else if (*dst == '/' || *dst == '\\') {
753 goto bad;
756 /* strip trailing gubbins */
757 if (dst > host && dst[-1] == '.') {
758 dst[-1] = '\0';
761 r->hostname = host;
762 return;
764 bad:
765 r->status = HTTP_BAD_REQUEST;
766 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
767 "Client sent malformed Host header");
768 return;
772 /* return 1 if host matches ServerName or ServerAliases */
773 static int matches_aliases(server_rec *s, const char *host)
775 int i;
776 apr_array_header_t *names;
778 /* match ServerName */
779 if (!strcasecmp(host, s->server_hostname)) {
780 return 1;
783 /* search all the aliases from ServerAlias directive */
784 names = s->names;
785 if (names) {
786 char **name = (char **) names->elts;
787 for (i = 0; i < names->nelts; ++i) {
788 if(!name[i]) continue;
789 if (!strcasecmp(host, name[i]))
790 return 1;
793 names = s->wild_names;
794 if (names) {
795 char **name = (char **) names->elts;
796 for (i = 0; i < names->nelts; ++i) {
797 if(!name[i]) continue;
798 if (!ap_strcasecmp_match(host, name[i]))
799 return 1;
802 return 0;
806 /* Suppose a request came in on the same socket as this r, and included
807 * a header "Host: host:port", would it map to r->server? It's more
808 * than just that though. When we do the normal matches for each request
809 * we don't even bother considering Host: etc on non-namevirtualhosts,
810 * we just call it a match. But here we require the host:port to match
811 * the ServerName and/or ServerAliases.
813 AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
814 apr_port_t port)
816 server_rec *s;
817 server_addr_rec *sar;
819 s = r->server;
821 /* search all the <VirtualHost> values */
822 /* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
823 * consider:
825 * NameVirtualHost 10.1.1.1
826 * <VirtualHost 10.1.1.1>
827 * ServerName v1
828 * </VirtualHost>
829 * <VirtualHost 10.1.1.1>
830 * ServerName v2
831 * </VirtualHost>
833 * Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
834 * "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
835 * it would really go to v1.
837 for (sar = s->addrs; sar; sar = sar->next) {
838 if ((sar->host_port == 0 || port == sar->host_port)
839 && !strcasecmp(host, sar->virthost)) {
840 return 1;
844 /* the Port has to match now, because the rest don't have ports associated
845 * with them. */
846 if (port != s->port) {
847 return 0;
850 return matches_aliases(s, host);
854 static void check_hostalias(request_rec *r)
857 * Even if the request has a Host: header containing a port we ignore
858 * that port. We always use the physical port of the socket. There
859 * are a few reasons for this:
861 * - the default of 80 or 443 for SSL is easier to handle this way
862 * - there is less of a possibility of a security problem
863 * - it simplifies the data structure
864 * - the client may have no idea that a proxy somewhere along the way
865 * translated the request to another ip:port
866 * - except for the addresses from the VirtualHost line, none of the other
867 * names we'll match have ports associated with them
869 const char *host = r->hostname;
870 apr_port_t port;
871 server_rec *s;
872 server_rec *last_s;
873 name_chain *src;
875 last_s = NULL;
877 port = r->connection->local_addr->port;
879 /* Recall that the name_chain is a list of server_addr_recs, some of
880 * whose ports may not match. Also each server may appear more than
881 * once in the chain -- specifically, it will appear once for each
882 * address from its VirtualHost line which matched. We only want to
883 * do the full ServerName/ServerAlias comparisons once for each
884 * server, fortunately we know that all the VirtualHost addresses for
885 * a single server are adjacent to each other.
888 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
889 server_addr_rec *sar;
891 /* We only consider addresses on the name_chain which have a matching
892 * port
894 sar = src->sar;
895 if (sar->host_port != 0 && port != sar->host_port) {
896 continue;
899 s = src->server;
901 /* does it match the virthost from the sar? */
902 if (!strcasecmp(host, sar->virthost)) {
903 goto found;
906 if (s == last_s) {
907 /* we've already done ServerName and ServerAlias checks for this
908 * vhost
910 continue;
912 last_s = s;
914 if (matches_aliases(s, host)) {
915 goto found;
918 return;
920 found:
921 /* s is the first matching server, we're done */
922 r->server = s;
926 static void check_serverpath(request_rec *r)
928 server_rec *s;
929 server_rec *last_s;
930 name_chain *src;
931 apr_port_t port;
933 port = r->connection->local_addr->port;
936 * This is in conjunction with the ServerPath code in http_core, so we
937 * get the right host attached to a non- Host-sending request.
939 * See the comment in check_hostalias about how each vhost can be
940 * listed multiple times.
943 last_s = NULL;
944 for (src = r->connection->vhost_lookup_data; src; src = src->next) {
945 /* We only consider addresses on the name_chain which have a matching
946 * port
948 if (src->sar->host_port != 0 && port != src->sar->host_port) {
949 continue;
952 s = src->server;
953 if (s == last_s) {
954 continue;
956 last_s = s;
958 if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
959 (s->path[s->pathlen - 1] == '/' ||
960 r->uri[s->pathlen] == '/' ||
961 r->uri[s->pathlen] == '\0')) {
962 r->server = s;
963 return;
969 AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
971 /* must set this for HTTP/1.1 support */
972 if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
973 fix_hostname(r);
974 if (r->status != HTTP_OK)
975 return;
977 /* check if we tucked away a name_chain */
978 if (r->connection->vhost_lookup_data) {
979 if (r->hostname)
980 check_hostalias(r);
981 else
982 check_serverpath(r);
987 * For every virtual host on this connection, call func_cb.
989 AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
990 ap_vhost_iterate_conn_cb func_cb,
991 void* baton)
993 server_rec *s;
994 server_rec *last_s;
995 name_chain *src;
996 apr_port_t port;
997 int rv = 0;
999 if (conn->vhost_lookup_data) {
1000 last_s = NULL;
1001 port = conn->local_addr->port;
1003 for (src = conn->vhost_lookup_data; src; src = src->next) {
1004 server_addr_rec *sar;
1006 /* We only consider addresses on the name_chain which have a
1007 * matching port.
1009 sar = src->sar;
1010 if (sar->host_port != 0 && port != sar->host_port) {
1011 continue;
1014 s = src->server;
1016 if (s == last_s) {
1017 /* we've already done a callback for this vhost. */
1018 continue;
1021 last_s = s;
1023 rv = func_cb(baton, conn, s);
1025 if (rv != 0) {
1026 break;
1030 else {
1031 rv = func_cb(baton, conn, conn->base_server);
1034 return rv;
1037 /* Called for a new connection which has a known local_addr. Note that the
1038 * new connection is assumed to have conn->server == main server.
1040 AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1042 ipaddr_chain *trav;
1043 apr_port_t port;
1045 /* scan the hash table for an exact match first */
1046 trav = find_ipaddr(conn->local_addr);
1048 if (trav) {
1049 /* save the name_chain for later in case this is a name-vhost */
1050 conn->vhost_lookup_data = trav->names;
1051 conn->base_server = trav->server;
1052 return;
1055 /* maybe there's a default server or wildcard name-based vhost
1056 * matching this port
1058 port = conn->local_addr->port;
1060 trav = find_default_server(port);
1061 if (trav) {
1062 conn->vhost_lookup_data = trav->names;
1063 conn->base_server = trav->server;
1064 return;
1067 /* otherwise we're stuck with just the main server
1068 * and no name-based vhosts
1070 conn->vhost_lookup_data = NULL;