static ngx_int_t
ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
{
    ngx_http_core_loc_conf_t  *clcf;
    ngx_http_core_srv_conf_t  *cscf;

    if (r->virtual_names == NULL) {
        return NGX_DECLINED;
    }

    cscf = ngx_hash_find_combined(&r->virtual_names->names,
                                  ngx_hash_key(host, len), host, len);

    if (cscf) {
        goto found;
    }

#if (NGX_PCRE)

    if (r->virtual_names->nregex) {
        size_t                   ncaptures;
        ngx_int_t                n;
        ngx_uint_t               i;
        ngx_str_t                name;
        ngx_http_server_name_t  *sn;

        name.len = len;
        name.data = host;

        ncaptures = 0;

        sn = r->virtual_names->regex;

        for (i = 0; i < r->virtual_names->nregex; i++) {

            if (sn[i].captures && r->captures == NULL) {

                ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;

                r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int));
                if (r->captures == NULL) {
                    return NGX_ERROR;
                }
            }

            n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);

            if (n == NGX_REGEX_NO_MATCHED) {
                continue;
            }

            if (n < 0) {
                ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
                              ngx_regex_exec_n
                              " failed: %d on \"%V\" using \"%V\"",
                              n, &name, &sn[i].name);
                return NGX_ERROR;
            }

            /* match */

            cscf = sn[i].core_srv_conf;

            r->ncaptures = ncaptures;
            r->captures_data = host;

            goto found;
        }
    }

#endif

    return NGX_OK;

found:

    r->srv_conf = cscf->ctx->srv_conf;
    r->loc_conf = cscf->ctx->loc_conf;

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
    r->connection->log->file = clcf->error_log->file;

    if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) {
        r->connection->log->log_level = clcf->error_log->log_level;
    }

    return NGX_OK;
}