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;
}

Reply via email to