VirtualHost名だけでなくServeAliasもみる

VirtualHost対応のために、アクセス時のホスト名とVirtualHost名をapacheモジュール内で比較させる方法がある。 しかし、これだけでは不十分で、実際にはServerAliasの設定がされているサーバーも多く、Aliasとマッチさせる必要もでてくる。 そのための関数を書いてみた。以下ソース。

static int check_virtualhost_name(request_rec *r) {

    int i;
    const char *header_name;
    const char *alias_name;

    header_name = apr_table_get(r->headers_in, "HOST");

    if (strcmp(header_name, r->server->server_hostname) == 0) {
        vlimit_debug_log_buf = apr_psprintf(r->pool, "Match: access_name=(%s) ServerName=(%s)"
            , header_name
            , r->server->server_hostname
        );
        VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);
        return 0;
    }

    for (i = 0; i < r->server->names->nelts; i++) {
        alias_name = (char **)r->server->names->elts + (r->server->names->elt_size * i);
        vlimit_debug_log_buf = apr_psprintf(r->pool, "INFO: access_name=(%s) ServerAlias=(%s)"
            , header_name
            , alias_name
        );
        VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);
        if (strcmp(header_name, alias_name) == 0 ) {
            vlimit_debug_log_buf = apr_psprintf(r->pool, "Match: access_name=(%s) ServerAlias=(%s)"
                , header_name
                , alias_name
            );
            VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);
            return 0;
        }
    }

    vlimit_debug_log_buf = apr_psprintf(r->pool, "Not Match: access_name=(%s)"
        , header_name
    );
    VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);

    return 1;
}

肝は以下の部分で、ServeAliasをあるだけ取得して、アクセスのあったホスト名と比較する。

for (i = 0; i < r->server->names->nelts; i++) {
    alias_name = (char **)r->server->names->elts + (r->server->names->elt_size * i);
    vlimit_debug_log_buf = apr_psprintf(r->pool, "INFO: access_name=(%s) ServerAlias=(%s)"
        , header_name
        , alias_name
    );
    VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);
    if (strcmp(header_name, alias_name) == 0 ) {
        vlimit_debug_log_buf = apr_psprintf(r->pool, "Match: access_name=(%s) ServerAlias=(%s)"
            , header_name
            , alias_name
        );
        VLIMIT_DEBUG_SYSLOG("check_virtualhost_name: ", vlimit_debug_log_buf, r->pool);
        return 0;
    }
}

重要というか、覚えておくべき実装はaprの動的配列部分で、neltsに配列数、eltsは配列要素が格納されている。 eltsはポインタのポインタであることにも注意しておきたい。