Commit 8638c1a0 authored by Colm MacCarthaigh's avatar Colm MacCarthaigh
Browse files

Improve the cache hit/miss ratio by canonicalising the url key. hostname's
are matched case-insensitively, port-based vhosts are catered for and the
scheme included for future multi-scheme caching compatibility.



git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@239407 13f79535-47bb-0310-9956-ffa450edef68
parent 9fc07d5f
Loading
Loading
Loading
Loading
+74 −4
Original line number Diff line number Diff line
@@ -320,12 +320,82 @@ int cache_select_url(request_rec *r, char *url)
apr_status_t cache_generate_key_default(request_rec *r, apr_pool_t* p,
                                        char**key)
{
    if (r->hostname) {
        *key = apr_pstrcat(p, r->hostname, r->uri, "?", r->args, NULL);
    char *port_str, *scheme, *hn;
    const char * hostname;
    int i;

    /* Use the canonical name to improve cache hit rate, but only if this is
     * not a proxy request. 
     */ 
    if (!r->proxyreq) {
        /* Use _default_ as the hostname if none present, as in mod_vhost */
        hostname =  ap_get_server_name(r);
        if (!hostname) {
            hostname = "_default_";
        }
    }
    else if(r->parsed_uri.hostname) {
        /* Copy the parsed uri hostname */
        hn = apr_pcalloc(p, strlen(r->parsed_uri.hostname) + 1);
        for (i = 0; r->parsed_uri.hostname[i]; i++) {
            hn[i] = apr_tolower(r->parsed_uri.hostname[i]);
        }
        /* const work-around */
        hostname = hn;
    }
    else {
        *key = apr_pstrcat(p, r->uri, "?", r->args, NULL);
        /* We are a proxied request, with no hostname. Unlikely
         * to get very far - but just in case */
        hostname = "_default_";
    }
    return APR_SUCCESS;

    /* Copy the scheme, ensuring that it is lower case. If the parsed uri
     * contains no string or if this is not a proxy request.
     */
    if (r->proxyreq && r->parsed_uri.scheme) {
        /* Copy the scheme */
        scheme = apr_pcalloc(p, strlen(r->parsed_uri.scheme) + 1);
        for (i = 0; r->parsed_uri.scheme[i]; i++) {
            scheme[i] = apr_tolower(r->parsed_uri.scheme[i]);
        }
    }
    else {
        scheme = "http";
    }

    /* If the content is locally generated, use the port-number of the
     * current server. Otherwise. copy the URI's port-string (which may be a
     * service name). If the URI contains no port-string, use apr-util's
     * notion of the default port for that scheme - if available.
     */
    if(r->proxyreq) {
        if (r->parsed_uri.port_str) {
            port_str = apr_pcalloc(p, strlen(r->parsed_uri.port_str) + 2);
            port_str[0] = ':';
            for (i = 0; r->parsed_uri.port_str[i]; i++) {
                port_str[i + 1] = apr_tolower(r->parsed_uri.port_str[i]);
            }
        }
        else if (apr_uri_port_of_scheme(scheme)) {
            port_str = apr_psprintf(p, ":%u", apr_uri_port_of_scheme(scheme));
        }
        else {
            /* No port string given in the AbsoluteUri, and we have no
             * idea what the default port for the scheme is. Leave it
             * blank and live with the inefficiency of some extra cached
             * entities.
             */
            port_str = "";
        }       
    }       
    else {
        /* Use the server port */
        port_str = apr_psprintf(p, ":%u", ap_get_server_port(r));
    }

    /* Key format is a URI */
    *key = apr_pstrcat(p, scheme, "://", hostname, port_str,
                       r->parsed_uri.path, "?", r->args, NULL);

    return APR_SUCCESS;
}