I'm looking for secure versions of ap_get_server_name and ap_get_server_port which can be trusted to always evaluate to the correct host and port for re-constructing the original URL the user requested. I've removed all of the code below which seemed to rely on DNS, or info sent from the client. Is the code below a sufficient minimal set to get working secure versions of those functions? I'm confused why there are so many different ways to get the hostname or port. It seems that if the ServerName directive is there it should return a value and that would be it. Also why would code like cport below ever be zero?
API_EXPORT(const char *) ap_get_server_name2(request_rec *r) { return r->hostname?r->hostname:r->server->server_hostname; } API_EXPORT(unsigned) ap_get_server_port2(const request_rec *r) { unsigned port; unsigned cport = ntohs(r->connection->local_addr.sin_port); port = cport ? cport : r->server->port ? r->server->port : ap_default_port(r); return port; } -Christopher Original apache 1.3 code ----------------------------------------------------------------------------------------------------------------- API_EXPORT(const char *) ap_get_server_name(request_rec *r) { conn_rec *conn = r->connection; core_dir_config *d; d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) { return r->hostname ? r->hostname : r->server->server_hostname; } if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { if (conn->local_host == NULL) { struct in_addr *iaddr; struct hostent *hptr; int old_stat; old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS, r); iaddr = &(conn->local_addr.sin_addr); hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET); if (hptr != NULL) { conn->local_host = ap_pstrdup(conn->pool, (void *)hptr->h_name); ap_str_tolower(conn->local_host); } else { conn->local_host = ap_pstrdup(conn->pool, r->server->server_hostname); } (void) ap_update_child_status(conn->child_num, old_stat, r); } return conn->local_host; } /* default */ return r->server->server_hostname; } API_EXPORT(unsigned) ap_get_server_port(const request_rec *r) { unsigned port; unsigned cport = ntohs(r->connection->local_addr.sin_port); core_dir_config *d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); if (d->use_canonical_name == USE_CANONICAL_NAME_OFF || d->use_canonical_name == USE_CANONICAL_NAME_DNS) { /* With UseCanonicalName Off Apache will form self-referential * URLs using the hostname and port supplied by the client if * any are supplied (otherwise it will use the canonical name). */ port = r->parsed_uri.port_str ? r->parsed_uri.port : cport ? cport : r->server->port ? r->server->port : ap_default_port(r); } else { /* d->use_canonical_name == USE_CANONICAL_NAME_ON */ port = r->server->port ? r->server->port : cport ? cport : ap_default_port(r); } /* default */ return port; }