Commit 606428ce authored by Brian Pane's avatar Brian Pane
Browse files

Performance fix: replaced the strcasecmp calls in ap_make_content_type()

with apr_strmatch()


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95026 13f79535-47bb-0310-9956-ffa450edef68
parent 6a2d0879
Loading
Loading
Loading
Loading
+3 −0
Changes for server/core.c: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -3851,9 +3851,12 @@ static apr_status_t core_output_filter(ap_filter_t *f, apr_bucket_brigade *b)
    return APR_SUCCESS;
}

AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool);

static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s)
{
    ap_set_version(pconf);
    ap_setup_make_content_type(pconf);
    return OK;
}

+32 −8
Changes for server/protocol.c: 32 added lines, 8 removed lines.
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
#include "apr_buckets.h"
#include "apr_lib.h"
#include "apr_signal.h"
#include "apr_strmatch.h"

#define APR_WANT_STDIO          /* for sscanf */
#define APR_WANT_STRFUNC
@@ -107,6 +108,30 @@ APR_HOOK_STRUCT(

AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;


/* Patterns to match in ap_make_content_type() */
static const char *needcset[] = {
    "text/plain",
    "text/html",
    NULL
};
static const apr_strmatch_pattern **needcset_patterns;
static const apr_strmatch_pattern *charset_pattern;

AP_DECLARE(void) ap_setup_make_content_type(apr_pool_t *pool)
{
    int i;
    for (i = 0; needcset[i]; i++) {
        continue;
    }
    needcset_patterns = (const apr_strmatch_pattern **)
        apr_palloc(pool, (i + 1) * sizeof(apr_strmatch_pattern *));
    for (i = 0; needcset[i]; i++) {
        needcset_patterns[i] = apr_strmatch_precompile(pool, needcset[i], 0);
    }
    charset_pattern = apr_strmatch_precompile(pool, "charset=", 0);
}

/*
 * Builds the content-type that should be sent to the client from the
 * content-type specified.  The following rules are followed:
@@ -117,14 +142,11 @@ AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;
 */
AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
{
    static const char *needcset[] = {
        "text/plain",
        "text/html",
        NULL };
    const char **pcset;
    const apr_strmatch_pattern **pcset;
    core_dir_config *conf =
        (core_dir_config *)ap_get_module_config(r->per_dir_config,
                                                &core_module);
    apr_size_t type_len;

    if (!type) {
        type = ap_default_type(r);
@@ -134,7 +156,9 @@ AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
        return type;
    }

    if (ap_strcasestr(type, "charset=") != NULL) {
    type_len = strlen(type);

    if (apr_strmatch(charset_pattern, type, type_len) != NULL) {
        /* already has parameter, do nothing */
        /* XXX we don't check the validity */
        ;
@@ -143,8 +167,8 @@ AP_DECLARE(const char *)ap_make_content_type(request_rec *r, const char *type)
        /* see if it makes sense to add the charset. At present,
         * we only add it if the Content-type is one of needcset[]
         */
        for (pcset = needcset; *pcset ; pcset++) {
            if (ap_strcasestr(type, *pcset) != NULL) {
        for (pcset = needcset_patterns; *pcset ; pcset++) {
            if (apr_strmatch(*pcset, type, type_len) != NULL) {
                type = apr_pstrcat(r->pool, type, "; charset=",
                                   conf->add_default_charset_name, NULL);
                break;