static char *ngx_http_small_light_pattern_define(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_small_light_conf_t *srv_conf;
    ngx_uint_t                   rc;
    ngx_str_t                   *ptn_name;
    ngx_str_t                   *ptn_str;
    ngx_str_t                   *value;
    ngx_hash_init_t              hash;
    
    srv_conf = conf;
    value    = cf->args->elts;
    ptn_name = &value[1];
    ptn_str  = &value[2];
    
    rc  = ngx_hash_add_key(&srv_conf->patterns, ptn_name, ptn_str->data, NGX_HASH_READONLY_KEY);

    if (rc != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    hash.hash        = &srv_conf->hash;
    hash.key         = ngx_hash_key_lc;
    hash.max_size    = 128;
    hash.bucket_size = ngx_cacheline_size;
    hash.name        = "small_light_pattern_define";
    hash.pool        = srv_conf->patterns.keys.pool;
    hash.temp_pool   = NULL;

    if (ngx_hash_init(&hash, srv_conf->patterns.keys.elts, srv_conf->patterns.keys.nelts) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}
예제 #2
0
ngx_int_t
ngx_http_variables_add_core_vars(ngx_conf_t *cf)
{//ngx_http_core_preconfiguration函数在程序解析配置之前就调用这里
//将ngx_http_core_variables 的变量全部导入到variables_keys里面,其里面会有各个handler来帮助存取变量值。
    ngx_int_t                   rc;
    ngx_http_variable_t        *v;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
    cmcf->variables_keys = ngx_pcalloc(cf->temp_pool, sizeof(ngx_hash_keys_arrays_t));
    if (cmcf->variables_keys == NULL) {
        return NGX_ERROR;
    }

    cmcf->variables_keys->pool = cf->pool;
    cmcf->variables_keys->temp_pool = cf->pool;
    if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL) != NGX_OK) {
        return NGX_ERROR;
    }
	//循环将这些变量加入到哈希表中。用户自定义的是不会存在这里面的,因为太多了。
    for (v = ngx_http_core_variables; v->name.len; v++) {
		//将著名的头部字段加入variables_keys,注意没有加入variables。为了效率。
        rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, NGX_HASH_READONLY_KEY);
        if (rc == NGX_OK) {
            continue;
        }
        if (rc == NGX_BUSY) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "conflicting variable name \"%V\"", &v->name);
        }
        return NGX_ERROR;
    }
    return NGX_OK;
}
예제 #3
0
static ngx_int_t
ngx_http_perl_preconfiguration(ngx_conf_t *cf)
{
#if (NGX_HTTP_SSI)
    ngx_int_t                  rc;
    ngx_http_ssi_main_conf_t  *smcf;

    smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_ssi_filter_module);

    rc = ngx_hash_add_key(&smcf->commands, &ngx_http_perl_ssi_command.name,
                          &ngx_http_perl_ssi_command, NGX_HASH_READONLY_KEY);

    if (rc != NGX_OK) {
        if (rc == NGX_BUSY) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "conflicting SSI command \"%V\"",
                               &ngx_http_perl_ssi_command.name);
        }

        return NGX_ERROR;
    }
#endif

    return NGX_OK;
}
예제 #4
0
파일: hash.c 프로젝트: deyimsf/journal
int main(){
	//数字对齐方法ngx_align用到了/os/unix/ngx_alloc.c中ngx_cacheline_size的值
	//如果不启动nginx则该值为0,这时ngx_align就一直返回为0,所以我们这给他一个默认值
	ngx_cacheline_size = 32;

	//用于构造带通配符的散列表
	ngx_hash_keys_arrays_t  ha;

	ngx_pool_t *pool = ngx_create_pool(2024, NULL);
	
	ha.temp_pool = pool;
	ha.pool = pool;

	if(ngx_hash_keys_array_init(&ha,NGX_HASH_LARGE) != NGX_OK){
		printf("初始化失败\n");	
	
		return 0;
	}

	
	//添加元素 *.jd.com
	ngx_str_t *key = ngx_pcalloc(pool, sizeof(ngx_str_t));
	key->len = ngx_strlen("*.com");
	key->data = ngx_pcalloc(pool, ngx_strlen("*.com"));
	ngx_memcpy(key->data, "*.com", ngx_strlen("*.com"));	

	int *value = ngx_pcalloc(pool, sizeof(int));
	*value = 1234; 

	ngx_int_t rc;
	rc = ngx_hash_add_key(&ha, key, value, NGX_HASH_WILDCARD_KEY);
        if(rc != NGX_OK){
		printf("添加key错误\n");
	}	

	//构造通配符散列表
	ngx_hash_init_t hash;
	hash.hash = NULL;
	hash.key = ngx_hash_key;
	hash.max_size = 10;
	hash.bucket_size = 100;
	hash.pool = pool;
	hash.temp_pool = pool;

	//初始化前置通配符散列表	
       	rc = ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
					ha.dns_wc_head.nelts);		

	if(rc != NGX_OK){
		printf("初始化通配符散列表错误\n");
	}
	
	// *.com和 as.dd.com a.b.c.com都匹配
	void *result = ngx_hash_find_wc_head((ngx_hash_wildcard_t *)hash.hash,
				"as.dd.com",ngx_strlen("as.dd.com"));
	
	int *bb = (int *)result;
	printf("%d\n",*bb);

}
static ngx_int_t
ngx_http_extravars_add_variables(ngx_conf_t *cf)
{
    ngx_int_t                   rc;
    ngx_http_variable_t        *v;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    for (v = ngx_http_extra_variables; v->name.len; v++) {
        rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
                              NGX_HASH_READONLY_KEY);

        if (rc == NGX_OK) {
            continue;
        }

        if (rc == NGX_BUSY) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "conflicting variable name \"%V\"", &v->name);
        }

        return NGX_ERROR;
    }

    return NGX_OK;
}
void* add_urls_to_array(ngx_pool_t *pool, ngx_hash_keys_arrays_t *ha, ngx_array_t *url, ngx_array_t *value)
{
	ngx_uint_t loop;
	ngx_int_t	rc;
	ngx_str_t	*strUrl, *strValue;
	
	memset(ha, 0, sizeof(ngx_hash_keys_arrays_t));
	ha->temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, &ngx_log);
	ha->pool = pool;
    if (ngx_hash_keys_array_init(ha, NGX_HASH_LARGE) != NGX_OK) {
        goto failed;
    }
	
	strUrl = url->elts;
	strValue = value->elts;
	for (loop = 0; loop < url->nelts; loop++)
	{
		rc = ngx_hash_add_key(ha, &strUrl[loop], &strValue[loop],
                                  NGX_HASH_WILDCARD_KEY);

            if (rc == NGX_ERROR) {
                goto failed;
            }
	}
    return ha;    

failed:
    ngx_destroy_pool(ha->temp_pool);
    return NULL;
}
ngx_int_t ngx_http_small_light_parse_params(ngx_http_request_t *r, ngx_http_small_light_ctx_t *ctx, ngx_str_t *define_pattern, char *pv)
{
    char *tk, *tv, *sp1, *sp2;
    char *k, *kk, *v, *vv;
    ngx_str_t ks;
    char p[BUFSIZ];
    if (define_pattern->len > BUFSIZ - 1) {
        return NGX_ERROR;
    }
    ngx_cpystrn((u_char *)p, define_pattern->data, define_pattern->len + 1);
    tk = strtok_r(p, ",", &sp1);
    while (tk != NULL) {
        tv = strtok_r(tk, "=", &sp2);
        k  = tv;
        v  = strtok_r(NULL, "=", &sp2);
        if (k == NULL || v == NULL) {
            return NGX_OK;
        }
        kk = ngx_palloc(r->pool, ngx_strlen(k) + 1);
        ngx_cpystrn((u_char *)kk, (u_char *)k, ngx_strlen(k) + 1);
        ks.data = (u_char *)kk;
        ks.len  = ngx_strlen(kk);
        if (ngx_strcmp(k, "p") == 0) {
            ngx_cpystrn((u_char *)pv, (u_char *)v, ngx_strlen(v) + 1);
        } else {
            vv = ngx_palloc(r->pool, ngx_strlen(v) + 1);
            ngx_cpystrn((u_char *)vv, (u_char *)v, ngx_strlen(v) + 1);
            ngx_hash_add_key(&ctx->params, &ks, vv, NGX_HASH_READONLY_KEY);
        }
        tk = strtok_r(NULL, ",", &sp1);
    }

    return NGX_OK;
}
예제 #8
0
ngx_http_variable_t *
ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
{//在cmcf->variables_keys里面查找有没有key相同的,如果有就返回,否则申请一个新的槽位。
//变量的get/set回调还没有设置,需要上层设置的。
    ngx_int_t                   rc;
    ngx_uint_t                  i;
    ngx_hash_key_t             *key;
    ngx_http_variable_t        *v;
    ngx_http_core_main_conf_t  *cmcf;

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    key = cmcf->variables_keys->keys.elts;
    for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
        if (name->len != key[i].key.len || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0) {
            continue;
        }
        v = key[i].value;
        if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the duplicate \"%V\" variable", name);
            return NULL;
        }
        return v;
    }
	//没有找到已有的,下面申请一个
    v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));
    if (v == NULL) {
        return NULL;
    }
    v->name.len = name->len;
    v->name.data = ngx_pnalloc(cf->pool, name->len);
    if (v->name.data == NULL) {
        return NULL;
    }
    ngx_strlow(v->name.data, name->data, name->len);
    v->set_handler = NULL;//回调需要上层设置。
    v->get_handler = NULL;
    v->data = 0;
    v->flags = flags;
    v->index = 0;//
    rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);
    if (rc == NGX_ERROR) {
        return NULL;
    }
    if (rc == NGX_BUSY) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "conflicting variable name \"%V\"", name);
        return NULL;
    }
    return v;
}
예제 #9
0
ngx_int_t
ngx_stream_variables_add_core_vars(ngx_conf_t *cf)
{
    ngx_int_t                     rc;
    ngx_stream_variable_t        *cv, *v;
    ngx_stream_core_main_conf_t  *cmcf;

    cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);

    cmcf->variables_keys = ngx_pcalloc(cf->temp_pool,
                                       sizeof(ngx_hash_keys_arrays_t));
    if (cmcf->variables_keys == NULL) {
        return NGX_ERROR;
    }

    cmcf->variables_keys->pool = cf->pool;
    cmcf->variables_keys->temp_pool = cf->pool;

    if (ngx_hash_keys_array_init(cmcf->variables_keys, NGX_HASH_SMALL)
        != NGX_OK)
    {
        return NGX_ERROR;
    }

    for (cv = ngx_stream_core_variables; cv->name.len; cv++) {
        v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t));
        if (v == NULL) {
            return NGX_ERROR;
        }

        *v = *cv;

        rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
                              NGX_HASH_READONLY_KEY);

        if (rc == NGX_OK) {
            continue;
        }

        if (rc == NGX_BUSY) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "conflicting variable name \"%V\"", &v->name);
        }

        return NGX_ERROR;
    }

    return NGX_OK;
}
static char *
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
    ngx_str_t *value, ngx_str_t *uri)
{
    ngx_int_t   rc;
    ngx_str_t  *u;

    if (uri->len == 0) {
        u = NGX_HTTP_REFERER_NO_URI_PART;

    } else {
        u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
        if (u == NULL) {
            return NGX_CONF_ERROR;
        }

        *u = *uri;
    }

    rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);

    if (rc == NGX_OK) {
        return NGX_CONF_OK;
    }

    if (rc == NGX_DECLINED) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid hostname or wildcard \"%V\"", value);
    }

    if (rc == NGX_BUSY) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "conflicting parameter \"%V\"", value);
    }

    return NGX_CONF_ERROR;
}
예제 #11
0
static char *
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
    ngx_int_t                   rc;
    ngx_str_t                  *value, file;
    ngx_uint_t                  i, key;
    ngx_http_map_conf_ctx_t    *ctx;
    ngx_http_variable_value_t  *var, **vp;

    ctx = cf->ctx;

    value = cf->args->elts;

    if (cf->args->nelts == 1
        && ngx_strcmp(value[0].data, "hostnames") == 0)
    {
        ctx->hostnames = 1;
        return NGX_CONF_OK;

    } else if (cf->args->nelts != 2) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid number of the map parameters");
        return NGX_CONF_ERROR;

    } else if (value[0].len == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid first parameter");
        return NGX_CONF_ERROR;
    }

    if (ngx_strcmp(value[0].data, "include") == 0) {
        file = value[1];

        if (ngx_conf_full_name(cf->cycle, &file) == NGX_ERROR){
            return NGX_CONF_ERROR;
        }

        ngx_log_debug1(NGX_LOG_DEBUG_CORE, cf->log, 0, "include %s", file.data);

        return ngx_conf_parse(cf, &file);
    }

    key = 0;

    for (i = 0; i < value[1].len; i++) {
        key = ngx_hash(key, value[1].data[i]);
    }

    key %= ctx->keys.hsize;

    vp = ctx->values_hash[key].elts;

    if (vp) {
        for (i = 0; i < ctx->values_hash[key].nelts; i++) {
            if (value[1].len != (size_t) vp[i]->len) {
                continue;
            }

            if (ngx_strncmp(value[1].data, vp[i]->data, value[1].len) == 0) {
                var = vp[i];
                goto found;
            }
        }

    } else {
        if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4,
                           sizeof(ngx_http_variable_value_t *))
            != NGX_OK)
        {
            return NGX_CONF_ERROR;
        }
    }

    var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));
    if (var == NULL) {
        return NGX_CONF_ERROR;
    }

    var->len = value[1].len;
    var->data = ngx_pstrdup(ctx->keys.pool, &value[1]);
    if (var->data == NULL) {
        return NGX_CONF_ERROR;
    }

    var->valid = 1;
    var->no_cacheable = 0;
    var->not_found = 0;

    vp = ngx_array_push(&ctx->values_hash[key]);
    if (vp == NULL) {
        return NGX_CONF_ERROR;
    }

    *vp = var;

found:

    if (ngx_strcmp(value[0].data, "default") == 0) {

        if (ctx->default_value) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "duplicate default map parameter");
            return NGX_CONF_ERROR;
        }

        ctx->default_value = var;

        return NGX_CONF_OK;
    }

    if (value[0].len && value[0].data[0] == '!') {
        value[0].len--;
        value[0].data++;
    }

    rc = ngx_hash_add_key(&ctx->keys, &value[0], var,
                          (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);

    if (rc == NGX_OK) {
        return NGX_CONF_OK;
    }

    if (rc == NGX_DECLINED) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid hostname or wildcard \"%V\"", &value[0]);
    }

    if (rc == NGX_BUSY) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "conflicting parameter \"%V\"", &value[0]);
    }

    return NGX_CONF_ERROR;
}
static void ngx_http_small_light_init_params_default(ngx_http_small_light_ctx_t *ctx)
{
    ngx_str_t p         = ngx_string("p");
    ngx_str_t sx        = ngx_string("sx");
    ngx_str_t sy        = ngx_string("sy");
    ngx_str_t sw        = ngx_string("sw");
    ngx_str_t sh        = ngx_string("sh");
    ngx_str_t dx        = ngx_string("dx");
    ngx_str_t dy        = ngx_string("dy");
    ngx_str_t dw        = ngx_string("dw");
    ngx_str_t dh        = ngx_string("dh");
    ngx_str_t da        = ngx_string("da");
    ngx_str_t ds        = ngx_string("ds");
    ngx_str_t cw        = ngx_string("cw");
    ngx_str_t ch        = ngx_string("ch");
    ngx_str_t cc        = ngx_string("cc");
    ngx_str_t bw        = ngx_string("bw");
    ngx_str_t bh        = ngx_string("bh");
    ngx_str_t bc        = ngx_string("bc");
    ngx_str_t pt        = ngx_string("pt");
    ngx_str_t q         = ngx_string("q");
    ngx_str_t of        = ngx_string("of");
    ngx_str_t info      = ngx_string("info");
    ngx_str_t inhexif   = ngx_string("inhexif");
    ngx_str_t jpeghint  = ngx_string("jpeghint");
    ngx_str_t rmprof    = ngx_string("rmprof");
    ngx_str_t embedicon = ngx_string("embedicon");
    ngx_str_t ix        = ngx_string("ix");
    ngx_str_t iy        = ngx_string("iy");
    ngx_str_t e         = ngx_string("e");

    ngx_hash_add_key(&ctx->params, &p,         "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &sx,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &sy,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &sw,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &sh,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &dx,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &dy,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &dw,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &dh,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &da,        "l",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &ds,        "n",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &cw,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &ch,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &cc,        "000000", NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &bw,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &bh,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &bc,        "000000", NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &pt,        "n",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &q,         "0",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &of,        "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &info,      "0",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &inhexif,   "n",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &jpeghint,  "n",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &rmprof,    "n",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &embedicon, "",       NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &ix,        "0",      NGX_HASH_READONLY_KEY);
    ngx_hash_add_key(&ctx->params, &iy,        "0",      NGX_HASH_READONLY_KEY);

    ngx_hash_add_key(&ctx->params, &e, NGX_HTTP_SMALL_LIGHT_CONVERTER_IMAGEMAGICK, NGX_HASH_READONLY_KEY);
}
예제 #13
0
파일: ngx_http.c 프로젝트: mlzboy/resys
static ngx_int_t
ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
    ngx_http_conf_addr_t *addr)
{
    ngx_int_t                   rc;
    ngx_uint_t                  n, s;
    ngx_hash_init_t             hash;
    ngx_hash_keys_arrays_t      ha;
    ngx_http_server_name_t     *name;
    ngx_http_core_srv_conf_t  **cscfp;
#if (NGX_PCRE)
    ngx_uint_t                  regex, i;

    regex = 0;
#endif

    ngx_memzero(&ha, sizeof(ngx_hash_keys_arrays_t));

    ha.temp_pool = ngx_create_pool(16384, cf->log);
    if (ha.temp_pool == NULL) {
        return NGX_ERROR;
    }

    ha.pool = cf->pool;

    if (ngx_hash_keys_array_init(&ha, NGX_HASH_LARGE) != NGX_OK) {
        goto failed;
    }

    cscfp = addr->servers.elts;

    for (s = 0; s < addr->servers.nelts; s++) {

        name = cscfp[s]->server_names.elts;

        for (n = 0; n < cscfp[s]->server_names.nelts; n++) {

#if (NGX_PCRE)
            if (name[n].regex) {
                regex++;
                continue;
            }
#endif

            rc = ngx_hash_add_key(&ha, &name[n].name, name[n].server,
                                  NGX_HASH_WILDCARD_KEY);

            if (rc == NGX_ERROR) {
                return NGX_ERROR;
            }

            if (rc == NGX_DECLINED) {
                ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                              "invalid server name or wildcard \"%V\" on %s",
                              &name[n].name, addr->opt.addr);
                return NGX_ERROR;
            }

            if (rc == NGX_BUSY) {
            ngx_log_error(NGX_LOG_WARN, cf->log, 0,
                              "conflicting server name \"%V\" on %s, ignored",
                              &name[n].name, addr->opt.addr);
            }
        }
    }

    hash.key = ngx_hash_key_lc;
    hash.max_size = cmcf->server_names_hash_max_size;
    hash.bucket_size = cmcf->server_names_hash_bucket_size;
    hash.name = "server_names_hash";
    hash.pool = cf->pool;

    if (ha.keys.nelts) {
        hash.hash = &addr->hash;
        hash.temp_pool = NULL;

        if (ngx_hash_init(&hash, ha.keys.elts, ha.keys.nelts) != NGX_OK) {
            goto failed;
        }
    }

    if (ha.dns_wc_head.nelts) {

        ngx_qsort(ha.dns_wc_head.elts, (size_t) ha.dns_wc_head.nelts,
                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);

        hash.hash = NULL;
        hash.temp_pool = ha.temp_pool;

        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_head.elts,
                                   ha.dns_wc_head.nelts)
            != NGX_OK)
        {
            goto failed;
        }

        addr->wc_head = (ngx_hash_wildcard_t *) hash.hash;
    }

    if (ha.dns_wc_tail.nelts) {

        ngx_qsort(ha.dns_wc_tail.elts, (size_t) ha.dns_wc_tail.nelts,
                  sizeof(ngx_hash_key_t), ngx_http_cmp_dns_wildcards);

        hash.hash = NULL;
        hash.temp_pool = ha.temp_pool;

        if (ngx_hash_wildcard_init(&hash, ha.dns_wc_tail.elts,
                                   ha.dns_wc_tail.nelts)
            != NGX_OK)
        {
            goto failed;
        }

        addr->wc_tail = (ngx_hash_wildcard_t *) hash.hash;
    }

    ngx_destroy_pool(ha.temp_pool);

#if (NGX_PCRE)

    if (regex == 0) {
        return NGX_OK;
    }

    addr->nregex = regex;
    addr->regex = ngx_palloc(cf->pool, regex * sizeof(ngx_http_server_name_t));
    if (addr->regex == NULL) {
        return NGX_ERROR;
    }

    i = 0;

    for (s = 0; s < addr->servers.nelts; s++) {

        name = cscfp[s]->server_names.elts;

        for (n = 0; n < cscfp[s]->server_names.nelts; n++) {
            if (name[n].regex) {
                addr->regex[i++] = name[n];
            }
        }
    }

#endif

    return NGX_OK;

failed:

    ngx_destroy_pool(ha.temp_pool);

    return NGX_ERROR;
}
예제 #14
0
ngx_stream_variable_t *
ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
{
    ngx_int_t                     rc;
    ngx_uint_t                    i;
    ngx_hash_key_t               *key;
    ngx_stream_variable_t        *v;
    ngx_stream_core_main_conf_t  *cmcf;

    if (name->len == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid variable name \"$\"");
        return NULL;
    }

    cmcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_core_module);

    key = cmcf->variables_keys->keys.elts;
    for (i = 0; i < cmcf->variables_keys->keys.nelts; i++) {
        if (name->len != key[i].key.len
            || ngx_strncasecmp(name->data, key[i].key.data, name->len) != 0)
        {
            continue;
        }

        v = key[i].value;

        if (!(v->flags & NGX_STREAM_VAR_CHANGEABLE)) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "the duplicate \"%V\" variable", name);
            return NULL;
        }

        return v;
    }

    v = ngx_palloc(cf->pool, sizeof(ngx_stream_variable_t));
    if (v == NULL) {
        return NULL;
    }

    v->name.len = name->len;
    v->name.data = ngx_pnalloc(cf->pool, name->len);
    if (v->name.data == NULL) {
        return NULL;
    }

    ngx_strlow(v->name.data, name->data, name->len);

    v->set_handler = NULL;
    v->get_handler = NULL;
    v->data = 0;
    v->flags = flags;
    v->index = 0;

    rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v, 0);

    if (rc == NGX_ERROR) {
        return NULL;
    }

    if (rc == NGX_BUSY) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "conflicting variable name \"%V\"", name);
        return NULL;
    }

    return v;
}
예제 #15
0
static char *
ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
    u_char                            *data;
    size_t                             len;
    ngx_int_t                          rv;
    ngx_str_t                         *value, v;
    ngx_uint_t                         i, key;
    ngx_http_map_conf_ctx_t           *ctx;
    ngx_http_complex_value_t           cv, *cvp;
    ngx_http_variable_value_t         *var, **vp;
    ngx_http_compile_complex_value_t   ccv;

    ctx = cf->ctx;

    value = cf->args->elts;

    if (cf->args->nelts == 1
        && ngx_strcmp(value[0].data, "hostnames") == 0)
    {
        ctx->hostnames = 1;
        return NGX_CONF_OK;
    }

    if (cf->args->nelts == 1
        && ngx_strcmp(value[0].data, "volatile") == 0)
    {
        ctx->no_cacheable = 1;
        return NGX_CONF_OK;
    }

    if (cf->args->nelts != 2) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid number of the map parameters");
        return NGX_CONF_ERROR;
    }

    if (ngx_strcmp(value[0].data, "include") == 0) {
        return ngx_conf_include(cf, dummy, conf);
    }

    key = 0;

    for (i = 0; i < value[1].len; i++) {
        key = ngx_hash(key, value[1].data[i]);
    }

    key %= ctx->keys.hsize;

    vp = ctx->values_hash[key].elts;

    if (vp) {
        for (i = 0; i < ctx->values_hash[key].nelts; i++) {

            if (vp[i]->valid) {
                data = vp[i]->data;
                len = vp[i]->len;

            } else {
                cvp = (ngx_http_complex_value_t *) vp[i]->data;
                data = cvp->value.data;
                len = cvp->value.len;
            }

            if (value[1].len != len) {
                continue;
            }

            if (ngx_strncmp(value[1].data, data, len) == 0) {
                var = vp[i];
                goto found;
            }
        }

    } else {
        if (ngx_array_init(&ctx->values_hash[key], cf->pool, 4,
                           sizeof(ngx_http_variable_value_t *))
            != NGX_OK)
        {
            return NGX_CONF_ERROR;
        }
    }

    var = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_variable_value_t));
    if (var == NULL) {
        return NGX_CONF_ERROR;
    }

    v.len = value[1].len;
    v.data = ngx_pstrdup(ctx->keys.pool, &value[1]);
    if (v.data == NULL) {
        return NGX_CONF_ERROR;
    }

    ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

    ccv.cf = ctx->cf;
    ccv.value = &v;
    ccv.complex_value = &cv;

    if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    if (cv.lengths != NULL) {
        cvp = ngx_palloc(ctx->keys.pool, sizeof(ngx_http_complex_value_t));
        if (cvp == NULL) {
            return NGX_CONF_ERROR;
        }

        *cvp = cv;

        var->len = 0;
        var->data = (u_char *) cvp;
        var->valid = 0;

    } else {
        var->len = v.len;
        var->data = v.data;
        var->valid = 1;
    }

    var->no_cacheable = 0;
    var->not_found = 0;

    vp = ngx_array_push(&ctx->values_hash[key]);
    if (vp == NULL) {
        return NGX_CONF_ERROR;
    }

    *vp = var;

found:

    if (ngx_strcmp(value[0].data, "default") == 0) {

        if (ctx->default_value) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "duplicate default map parameter");
            return NGX_CONF_ERROR;
        }

        ctx->default_value = var;

        return NGX_CONF_OK;
    }

#if (NGX_PCRE)

    if (value[0].len && value[0].data[0] == '~') {
        ngx_regex_compile_t    rc;
        ngx_http_map_regex_t  *regex;
        u_char                 errstr[NGX_MAX_CONF_ERRSTR];

        regex = ngx_array_push(&ctx->regexes);
        if (regex == NULL) {
            return NGX_CONF_ERROR;
        }

        value[0].len--;
        value[0].data++;

        ngx_memzero(&rc, sizeof(ngx_regex_compile_t));

        if (value[0].data[0] == '*') {
            value[0].len--;
            value[0].data++;
            rc.options = NGX_REGEX_CASELESS;
        }

        rc.pattern = value[0];
        rc.err.len = NGX_MAX_CONF_ERRSTR;
        rc.err.data = errstr;

        regex->regex = ngx_http_regex_compile(ctx->cf, &rc);
        if (regex->regex == NULL) {
            return NGX_CONF_ERROR;
        }

        regex->value = var;

        return NGX_CONF_OK;
    }

#endif

    if (value[0].len && value[0].data[0] == '\\') {
        value[0].len--;
        value[0].data++;
    }

    rv = ngx_hash_add_key(&ctx->keys, &value[0], var,
                          (ctx->hostnames) ? NGX_HASH_WILDCARD_KEY : 0);

    if (rv == NGX_OK) {
        return NGX_CONF_OK;
    }

    if (rv == NGX_DECLINED) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid hostname or wildcard \"%V\"", &value[0]);
    }

    if (rv == NGX_BUSY) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "conflicting parameter \"%V\"", &value[0]);
    }

    return NGX_CONF_ERROR;
}