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
31
#include "ap_config.h"
33
#include "http_config.h"
35
#include "http_vhost.h"
36
#include "http_protocol.h"
37
#include "http_core.h"
39
#if APR_HAVE_ARPA_INET_H
40
#include <arpa/inet.h>
44
* After all the definitions there's an explanation of how it's all put
48
/* meta-list of name-vhosts. Each server_rec can be in possibly multiple
49
* lists of name-vhosts.
51
typedef struct name_chain name_chain;
54
server_addr_rec *sar; /* the record causing it to be in
55
* this chain (needed for port comparisons) */
56
server_rec *server; /* the server to use on a match */
59
/* meta-list of ip addresses. Each server_rec can be in possibly multiple
60
* hash chains since it can have multiple ips.
62
typedef struct ipaddr_chain ipaddr_chain;
65
server_addr_rec *sar; /* the record causing it to be in
66
* this chain (need for both ip addr and port
68
server_rec *server; /* the server to use if this matches */
69
name_chain *names; /* if non-NULL then a list of name-vhosts
70
* sharing this address */
73
/* This defines the size of the hash table used for hashing ip addresses
74
* of virtual hosts. It must be a power of two.
76
#ifndef IPHASH_TABLE_SIZE
77
#define IPHASH_TABLE_SIZE 256
80
/* A (n) bucket hash table, each entry has a pointer to a server rec and
81
* a pointer to the other entries in that bucket. Each individual address,
82
* even for virtualhosts with multiple addresses, has an entry in this hash
83
* table. There are extra buckets for _default_, and name-vhost entries.
85
* Note that after config time this is constant, so it is thread-safe.
87
static ipaddr_chain *iphash_table[IPHASH_TABLE_SIZE];
89
/* dump out statistics about the hash function */
90
/* #define IPHASH_STATISTICS */
92
/* list of the _default_ servers */
93
static ipaddr_chain *default_list;
95
/* list of the NameVirtualHost addresses */
96
static server_addr_rec *name_vhost_list;
97
static server_addr_rec **name_vhost_list_tail;
102
* The ip address determines which chain in iphash_table is interesting, then
103
* a comparison is done down that chain to find the first ipaddr_chain whose
104
* sar matches the address:port pair.
106
* If that ipaddr_chain has names == NULL then you're done, it's an ip-vhost.
108
* Otherwise it's a name-vhost list, and the default is the server in the
109
* ipaddr_chain record. We tuck away the ipaddr_chain record in the
110
* conn_rec field vhost_lookup_data. Later on after the headers we get a
111
* second chance, and we use the name_chain to figure out what name-vhost
112
* matches the headers.
114
* If there was no ip address match in the iphash_table then do a lookup
115
* in the default_list.
117
* How it's put together ... well you should be able to figure that out
118
* from how it's used. Or something like that.
122
/* called at the beginning of the config */
123
AP_DECLARE(void) ap_init_vhost_config(apr_pool_t *p)
125
memset(iphash_table, 0, sizeof(iphash_table));
127
name_vhost_list = NULL;
128
name_vhost_list_tail = &name_vhost_list;
133
* Parses a host of the form <address>[:port]
134
* paddr is used to create a list in the order of input
135
* **paddr is the ->next pointer of the last entry (or s->addrs)
136
* *paddr is the variable used to keep track of **paddr between calls
137
* port is the default port to assume
139
static const char *get_addresses(apr_pool_t *p, const char *w_,
140
server_addr_rec ***paddr,
141
apr_port_t default_port)
143
apr_sockaddr_t *my_addr;
144
server_addr_rec *sar;
145
char *w, *host, *scope_id;
154
w = apr_pstrdup(p, w_);
155
/* apr_parse_addr_port() doesn't understand ":*" so handle that first. */
156
wlen = strlen(w); /* wlen must be > 0 at this point */
158
if (w[wlen - 1] == '*') {
162
else if (w[wlen - 2] == ':') {
167
rv = apr_parse_addr_port(&host, &scope_id, &port, w, p);
168
/* If the string is "80", apr_parse_addr_port() will be happy and set
169
* host to NULL and port to 80, so watch out for that.
171
if (rv != APR_SUCCESS) {
172
return "The address or port is invalid";
175
return "Missing address for VirtualHost";
178
return "Scope ids are not supported";
180
if (!port && !wild_port) {
184
if (strcmp(host, "*") == 0) {
185
rv = apr_sockaddr_info_get(&my_addr, "0.0.0.0", APR_INET, port, 0, p);
187
return "Could not resolve address '0.0.0.0' -- "
188
"check resolver configuration.";
191
else if (strcasecmp(host, "_default_") == 0
192
|| strcmp(host, "255.255.255.255") == 0) {
193
rv = apr_sockaddr_info_get(&my_addr, "255.255.255.255", APR_INET, port, 0, p);
195
return "Could not resolve address '255.255.255.255' -- "
196
"check resolver configuration.";
200
rv = apr_sockaddr_info_get(&my_addr, host, APR_UNSPEC, port, 0, p);
201
if (rv != APR_SUCCESS) {
202
ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL,
203
"Could not resolve host name %s -- ignoring!", host);
208
/* Remember all addresses for the host */
211
sar = apr_pcalloc(p, sizeof(server_addr_rec));
214
sar->host_addr = my_addr;
215
sar->host_port = port;
216
sar->virthost = host;
217
my_addr = my_addr->next;
224
/* parse the <VirtualHost> addresses */
225
const char *ap_parse_vhost_addrs(apr_pool_t *p,
226
const char *hostname,
229
server_addr_rec **addrs;
232
/* start the list of addreses */
234
while (hostname[0]) {
235
err = get_addresses(p, ap_getword_conf(p, &hostname), &addrs, s->port);
241
/* terminate the list */
244
if (s->addrs->host_port) {
245
/* override the default port which is inherited from main_server */
246
s->port = s->addrs->host_port;
253
const char *ap_set_name_virtual_host(cmd_parms *cmd, void *dummy,
256
/* use whatever port the main server has at this point */
257
return get_addresses(cmd->pool, arg, &name_vhost_list_tail,
262
/* hash table statistics, keep this in here for the beta period so
263
* we can find out if the hash function is ok
265
#ifdef IPHASH_STATISTICS
266
static int iphash_compare(const void *a, const void *b)
268
return (*(const int *) b - *(const int *) a);
272
static void dump_iphash_statistics(server_rec *main_s)
274
unsigned count[IPHASH_TABLE_SIZE];
278
char buf[HUGE_STRING_LEN];
282
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
284
for (src = iphash_table[i]; src; src = src->next) {
286
if (i < IPHASH_TABLE_SIZE) {
287
/* don't count the slop buckets in the total */
292
qsort(count, IPHASH_TABLE_SIZE, sizeof(count[0]), iphash_compare);
293
p = buf + apr_snprintf(buf, sizeof(buf),
294
"iphash: total hashed = %u, avg chain = %u, "
295
"chain lengths (count x len):",
296
total, total / IPHASH_TABLE_SIZE);
298
for (i = 1; i < IPHASH_TABLE_SIZE; ++i) {
299
if (count[i - 1] != count[i]) {
300
p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
301
total, count[i - 1]);
308
p += apr_snprintf(p, sizeof(buf) - (p - buf), " %ux%u",
309
total, count[IPHASH_TABLE_SIZE - 1]);
310
ap_log_error(APLOG_MARK, APLOG_DEBUG, main_s, buf);
315
/* This hashing function is designed to get good distribution in the cases
316
* where the server is handling entire "networks" of servers. i.e. a
317
* whack of /24s. This is probably the most common configuration for
318
* ISPs with large virtual servers.
320
* NOTE: This function is symmetric (i.e. collapses all 4 octets
321
* into one), so machine byte order (big/little endianness) does not matter.
323
* Hash function provided by David Hankins.
325
static APR_INLINE unsigned hash_inaddr(unsigned key)
328
return ((key >> 8) ^ key) % IPHASH_TABLE_SIZE;
331
static APR_INLINE unsigned hash_addr(struct apr_sockaddr_t *sa)
335
/* The key is the last four bytes of the IP address.
336
* For IPv4, this is the entire address, as always.
337
* For IPv6, this is usually part of the MAC address.
339
key = *(unsigned *)((char *)sa->ipaddr_ptr + sa->ipaddr_len - 4);
340
return hash_inaddr(key);
343
static ipaddr_chain *new_ipaddr_chain(apr_pool_t *p,
344
server_rec *s, server_addr_rec *sar)
348
new = apr_palloc(p, sizeof(*new));
357
static name_chain *new_name_chain(apr_pool_t *p,
358
server_rec *s, server_addr_rec *sar)
362
new = apr_palloc(p, sizeof(*new));
370
static APR_INLINE ipaddr_chain *find_ipaddr(apr_sockaddr_t *sa)
375
/* scan the hash table for an exact match first */
376
bucket = hash_addr(sa);
377
for (trav = iphash_table[bucket]; trav; trav = trav->next) {
378
server_addr_rec *sar = trav->sar;
379
apr_sockaddr_t *cur = sar->host_addr;
381
if (cur->port == 0 || sa->port == 0 || cur->port == sa->port) {
382
if (apr_sockaddr_equal(cur, sa)) {
390
static ipaddr_chain *find_default_server(apr_port_t port)
392
server_addr_rec *sar;
395
for (trav = default_list; trav; trav = trav->next) {
397
if (sar->host_port == 0 || sar->host_port == port) {
405
static void dump_a_vhost(apr_file_t *f, ipaddr_chain *ic)
409
char buf[MAX_STRING_LEN];
410
apr_sockaddr_t *ha = ic->sar->host_addr;
412
if (ha->family == APR_INET &&
413
ha->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR) {
414
len = apr_snprintf(buf, sizeof(buf), "_default_:%u",
417
else if (ha->family == APR_INET &&
418
ha->sa.sin.sin_addr.s_addr == INADDR_ANY) {
419
len = apr_snprintf(buf, sizeof(buf), "*:%u",
423
len = apr_snprintf(buf, sizeof(buf), "%pI", ha);
425
if (ic->sar->host_port == 0) {
428
if (ic->names == NULL) {
429
apr_file_printf(f, "%-22s %s (%s:%u)\n", buf,
430
ic->server->server_hostname,
431
ic->server->defn_name, ic->server->defn_line_number);
434
apr_file_printf(f, "%-22s is a NameVirtualHost\n"
435
"%8s default server %s (%s:%u)\n",
436
buf, "", ic->server->server_hostname,
437
ic->server->defn_name, ic->server->defn_line_number);
438
for (nc = ic->names; nc; nc = nc->next) {
439
if (nc->sar->host_port) {
440
apr_file_printf(f, "%8s port %u ", "", nc->sar->host_port);
443
apr_file_printf(f, "%8s port * ", "");
445
apr_file_printf(f, "namevhost %s (%s:%u)\n",
446
nc->server->server_hostname,
447
nc->server->defn_name, nc->server->defn_line_number);
451
static void dump_vhost_config(apr_file_t *f)
456
apr_file_printf(f, "VirtualHost configuration:\n");
457
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
458
for (ic = iphash_table[i]; ic; ic = ic->next) {
463
apr_file_printf(f, "wildcard NameVirtualHosts and _default_ servers:\n");
464
for (ic = default_list; ic; ic = ic->next) {
471
* Two helper functions for ap_fini_vhost_config()
473
static int add_name_vhost_config(apr_pool_t *p, server_rec *main_s,
474
server_rec *s, server_addr_rec *sar,
477
/* the first time we encounter a NameVirtualHost address
478
* ic->server will be NULL, on subsequent encounters
479
* ic->names will be non-NULL.
481
if (ic->names || ic->server == NULL) {
482
name_chain *nc = new_name_chain(p, s, sar);
483
nc->next = ic->names;
486
if (sar->host_port != ic->sar->host_port) {
487
/* one of the two is a * port, the other isn't */
488
ap_log_error(APLOG_MARK, APLOG_ERR, 0, main_s,
489
"VirtualHost %s:%u -- mixing * "
490
"ports and non-* ports with "
491
"a NameVirtualHost address is not supported,"
492
" proceeding with undefined results",
493
sar->virthost, sar->host_port);
498
/* IP-based vhosts are handled by the caller */
503
static void remove_unused_name_vhosts(server_rec *main_s, ipaddr_chain **pic)
506
ipaddr_chain *ic = *pic;
508
if (ic->server == NULL) {
509
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, main_s,
510
"NameVirtualHost %s:%u has no VirtualHosts",
511
ic->sar->virthost, ic->sar->host_port);
520
/* compile the tables and such we need to do the run-time vhost lookups */
521
AP_DECLARE(void) ap_fini_vhost_config(apr_pool_t *p, server_rec *main_s)
523
server_addr_rec *sar;
524
int has_default_vhost_addr;
527
ipaddr_chain **iphash_table_tail[IPHASH_TABLE_SIZE];
529
/* terminate the name_vhost list */
530
*name_vhost_list_tail = NULL;
532
/* Main host first */
535
if (!s->server_hostname) {
536
s->server_hostname = ap_get_local_host(p);
539
/* initialize the tails */
540
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
541
iphash_table_tail[i] = &iphash_table[i];
544
/* The first things to go into the hash table are the NameVirtualHosts
545
* Since name_vhost_list is in the same order that the directives
546
* occured in the config file, we'll copy it in that order.
548
for (sar = name_vhost_list; sar; sar = sar->next) {
549
char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
550
unsigned bucket = hash_addr(sar->host_addr);
551
ipaddr_chain *ic = new_ipaddr_chain(p, NULL, sar);
553
if (memcmp(sar->host_addr->ipaddr_ptr, inaddr_any,
554
sar->host_addr->ipaddr_len)) { /* not IN[6]ADDR_ANY */
555
*iphash_table_tail[bucket] = ic;
556
iphash_table_tail[bucket] = &ic->next;
559
/* A wildcard NameVirtualHost goes on the default_list so
560
* that it can catch incoming requests on any address.
562
ic->next = default_list;
565
/* Notice that what we've done is insert an ipaddr_chain with
566
* both server and names NULL. This fact is used to spot name-
567
* based vhosts in add_name_vhost_config().
571
/* The next things to go into the hash table are the virtual hosts
572
* themselves. They're listed off of main_s->next in the reverse
573
* order they occured in the config file, so we insert them at
574
* the iphash_table_tail but don't advance the tail.
577
for (s = main_s->next; s; s = s->next) {
578
has_default_vhost_addr = 0;
579
for (sar = s->addrs; sar; sar = sar->next) {
581
char inaddr_any[16] = {0}; /* big enough to handle IPv4 or IPv6 */
583
if ((sar->host_addr->family == AF_INET &&
584
sar->host_addr->sa.sin.sin_addr.s_addr == DEFAULT_VHOST_ADDR)
585
|| !memcmp(sar->host_addr->ipaddr_ptr, inaddr_any, sar->host_addr->ipaddr_len)) {
586
ic = find_default_server(sar->host_port);
587
if (!ic || !add_name_vhost_config(p, main_s, s, sar, ic)) {
588
if (ic && ic->sar->host_port != 0) {
589
ap_log_error(APLOG_MARK, APLOG_WARNING,
590
0, main_s, "_default_ VirtualHost "
591
"overlap on port %u, the first has "
592
"precedence", sar->host_port);
594
ic = new_ipaddr_chain(p, s, sar);
595
ic->next = default_list;
598
has_default_vhost_addr = 1;
601
/* see if it matches something we've already got */
602
ic = find_ipaddr(sar->host_addr);
605
unsigned bucket = hash_addr(sar->host_addr);
607
ic = new_ipaddr_chain(p, s, sar);
608
ic->next = *iphash_table_tail[bucket];
609
*iphash_table_tail[bucket] = ic;
611
else if (!add_name_vhost_config(p, main_s, s, sar, ic)) {
612
ap_log_error(APLOG_MARK, APLOG_WARNING,
613
0, main_s, "VirtualHost %s:%u overlaps "
614
"with VirtualHost %s:%u, the first has "
615
"precedence, perhaps you need a "
616
"NameVirtualHost directive",
617
sar->virthost, sar->host_port,
618
ic->sar->virthost, ic->sar->host_port);
625
/* Ok now we want to set up a server_hostname if the user was
626
* silly enough to forget one.
627
* XXX: This is silly we should just crash and burn.
629
if (!s->server_hostname) {
630
if (has_default_vhost_addr) {
631
s->server_hostname = main_s->server_hostname;
633
else if (!s->addrs) {
634
/* what else can we do? at this point this vhost has
635
no configured name, probably because they used
636
DNS in the VirtualHost statement. It's disabled
637
anyhow by the host matching code. -djg */
639
apr_pstrdup(p, "bogus_host_without_forward_dns");
645
rv = apr_getnameinfo(&hostname, s->addrs->host_addr, 0);
646
if (rv == APR_SUCCESS) {
647
s->server_hostname = apr_pstrdup(p, hostname);
650
/* again, what can we do? They didn't specify a
651
ServerName, and their DNS isn't working. -djg */
654
apr_sockaddr_ip_get(&ipaddr_str, s->addrs->host_addr);
655
ap_log_error(APLOG_MARK, APLOG_ERR, rv, main_s,
656
"Failed to resolve server name "
657
"for %s (check DNS) -- or specify an explicit "
661
apr_pstrdup(p, "bogus_host_without_reverse_dns");
667
/* now go through and delete any NameVirtualHosts that didn't have any
668
* hosts associated with them. Lamers.
670
for (i = 0; i < IPHASH_TABLE_SIZE; ++i) {
671
remove_unused_name_vhosts(main_s, &iphash_table[i]);
673
remove_unused_name_vhosts(main_s, &default_list);
675
#ifdef IPHASH_STATISTICS
676
dump_iphash_statistics(main_s);
678
if (ap_exists_config_define("DUMP_VHOSTS")) {
679
apr_file_t *thefile = NULL;
680
apr_file_open_stderr(&thefile, p);
681
dump_vhost_config(thefile);
686
/*****************************************************************************
687
* run-time vhost matching functions
690
/* Lowercase and remove any trailing dot and/or :port from the hostname,
691
* and check that it is sane.
693
* In most configurations the exact syntax of the hostname isn't
694
* important so strict sanity checking isn't necessary. However, in
695
* mass hosting setups (using mod_vhost_alias or mod_rewrite) where
696
* the hostname is interpolated into the filename, we need to be sure
697
* that the interpolation doesn't expose parts of the filesystem.
698
* We don't do strict RFC 952 / RFC 1123 syntax checking in order
699
* to support iDNS and people who erroneously use underscores.
700
* Instead we just check for filesystem metacharacters: directory
701
* separators / and \ and sequences of more than one dot.
703
static void fix_hostname(request_rec *r)
705
char *host, *scope_id;
710
/* According to RFC 2616, Host header field CAN be blank. */
715
rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool);
716
if (rv != APR_SUCCESS || scope_id) {
721
/* silly looking host ("Host: 123") but that isn't our job
722
* here to judge; apr_parse_addr_port() would think we had a port
725
host = apr_itoa(r->pool, (int)port);
728
/* Don't throw the Host: header's port number away:
729
save it in parsed_uri -- ap_get_server_port() needs it! */
730
/* @@@ XXX there should be a better way to pass the port.
731
* Like r->hostname, there should be a r->portno
733
r->parsed_uri.port = port;
734
r->parsed_uri.port_str = apr_itoa(r->pool, (int)port);
737
/* if the hostname is an IPv6 numeric address string, it was validated
738
* already; otherwise, further validation is needed
740
if (r->hostname[0] != '[') {
741
for (dst = host; *dst; dst++) {
742
if (apr_islower(*dst)) {
743
/* leave char unchanged */
745
else if (*dst == '.') {
746
if (*(dst + 1) == '.') {
750
else if (apr_isupper(*dst)) {
751
*dst = apr_tolower(*dst);
753
else if (*dst == '/' || *dst == '\\') {
757
/* strip trailing gubbins */
758
if (dst > host && dst[-1] == '.') {
766
r->status = HTTP_BAD_REQUEST;
767
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
768
"Client sent malformed Host header");
773
/* return 1 if host matches ServerName or ServerAliases */
774
static int matches_aliases(server_rec *s, const char *host)
777
apr_array_header_t *names;
779
/* match ServerName */
780
if (!strcasecmp(host, s->server_hostname)) {
784
/* search all the aliases from ServerAlias directive */
787
char **name = (char **) names->elts;
788
for (i = 0; i < names->nelts; ++i) {
789
if(!name[i]) continue;
790
if (!strcasecmp(host, name[i]))
794
names = s->wild_names;
796
char **name = (char **) names->elts;
797
for (i = 0; i < names->nelts; ++i) {
798
if(!name[i]) continue;
799
if (!ap_strcasecmp_match(host, name[i]))
807
/* Suppose a request came in on the same socket as this r, and included
808
* a header "Host: host:port", would it map to r->server? It's more
809
* than just that though. When we do the normal matches for each request
810
* we don't even bother considering Host: etc on non-namevirtualhosts,
811
* we just call it a match. But here we require the host:port to match
812
* the ServerName and/or ServerAliases.
814
AP_DECLARE(int) ap_matches_request_vhost(request_rec *r, const char *host,
818
server_addr_rec *sar;
822
/* search all the <VirtualHost> values */
823
/* XXX: If this is a NameVirtualHost then we may not be doing the Right Thing
826
* NameVirtualHost 10.1.1.1
827
* <VirtualHost 10.1.1.1>
830
* <VirtualHost 10.1.1.1>
834
* Suppose r->server is v2, and we're asked to match "10.1.1.1". We'll say
835
* "yup it's v2", when really it isn't... if a request came in for 10.1.1.1
836
* it would really go to v1.
838
for (sar = s->addrs; sar; sar = sar->next) {
839
if ((sar->host_port == 0 || port == sar->host_port)
840
&& !strcasecmp(host, sar->virthost)) {
845
/* the Port has to match now, because the rest don't have ports associated
847
if (port != s->port) {
851
return matches_aliases(s, host);
855
static void check_hostalias(request_rec *r)
858
* Even if the request has a Host: header containing a port we ignore
859
* that port. We always use the physical port of the socket. There
860
* are a few reasons for this:
862
* - the default of 80 or 443 for SSL is easier to handle this way
863
* - there is less of a possibility of a security problem
864
* - it simplifies the data structure
865
* - the client may have no idea that a proxy somewhere along the way
866
* translated the request to another ip:port
867
* - except for the addresses from the VirtualHost line, none of the other
868
* names we'll match have ports associated with them
870
const char *host = r->hostname;
878
port = r->connection->local_addr->port;
880
/* Recall that the name_chain is a list of server_addr_recs, some of
881
* whose ports may not match. Also each server may appear more than
882
* once in the chain -- specifically, it will appear once for each
883
* address from its VirtualHost line which matched. We only want to
884
* do the full ServerName/ServerAlias comparisons once for each
885
* server, fortunately we know that all the VirtualHost addresses for
886
* a single server are adjacent to each other.
889
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
890
server_addr_rec *sar;
892
/* We only consider addresses on the name_chain which have a matching
896
if (sar->host_port != 0 && port != sar->host_port) {
902
/* does it match the virthost from the sar? */
903
if (!strcasecmp(host, sar->virthost)) {
908
/* we've already done ServerName and ServerAlias checks for this
915
if (matches_aliases(s, host)) {
922
/* s is the first matching server, we're done */
927
static void check_serverpath(request_rec *r)
934
port = r->connection->local_addr->port;
937
* This is in conjunction with the ServerPath code in http_core, so we
938
* get the right host attached to a non- Host-sending request.
940
* See the comment in check_hostalias about how each vhost can be
941
* listed multiple times.
945
for (src = r->connection->vhost_lookup_data; src; src = src->next) {
946
/* We only consider addresses on the name_chain which have a matching
949
if (src->sar->host_port != 0 && port != src->sar->host_port) {
959
if (s->path && !strncmp(r->uri, s->path, s->pathlen) &&
960
(s->path[s->pathlen - 1] == '/' ||
961
r->uri[s->pathlen] == '/' ||
962
r->uri[s->pathlen] == '\0')) {
970
AP_DECLARE(void) ap_update_vhost_from_headers(request_rec *r)
972
/* must set this for HTTP/1.1 support */
973
if (r->hostname || (r->hostname = apr_table_get(r->headers_in, "Host"))) {
975
if (r->status != HTTP_OK)
978
/* check if we tucked away a name_chain */
979
if (r->connection->vhost_lookup_data) {
988
* For every virtual host on this connection, call func_cb.
990
AP_DECLARE(int) ap_vhost_iterate_given_conn(conn_rec *conn,
991
ap_vhost_iterate_conn_cb func_cb,
1000
if (conn->vhost_lookup_data) {
1002
port = conn->local_addr->port;
1004
for (src = conn->vhost_lookup_data; src; src = src->next) {
1005
server_addr_rec *sar;
1007
/* We only consider addresses on the name_chain which have a
1011
if (sar->host_port != 0 && port != sar->host_port) {
1018
/* we've already done a callback for this vhost. */
1024
rv = func_cb(baton, conn, s);
1032
rv = func_cb(baton, conn, conn->base_server);
1038
/* Called for a new connection which has a known local_addr. Note that the
1039
* new connection is assumed to have conn->server == main server.
1041
AP_DECLARE(void) ap_update_vhost_given_ip(conn_rec *conn)
1046
/* scan the hash table for an exact match first */
1047
trav = find_ipaddr(conn->local_addr);
1050
/* save the name_chain for later in case this is a name-vhost */
1051
conn->vhost_lookup_data = trav->names;
1052
conn->base_server = trav->server;
1056
/* maybe there's a default server or wildcard name-based vhost
1057
* matching this port
1059
port = conn->local_addr->port;
1061
trav = find_default_server(port);
1063
conn->vhost_lookup_data = trav->names;
1064
conn->base_server = trav->server;
1068
/* otherwise we're stuck with just the main server
1069
* and no name-based vhosts
1071
conn->vhost_lookup_data = NULL;