static char * ngx_http_tfs_rcs_zone(ngx_conf_t *cf, ngx_http_tfs_upstream_t *tu) { ssize_t size; ngx_str_t *value, s, name; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_tfs_rc_ctx_t *ctx; value = cf->args->elts; size = 0; name.len = 0; if (cf->args->nelts != 3) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number of arguments in " "\"rcs_zone\" directive"); return NGX_CONF_ERROR; } for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "size=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "name=", 5) == 0) { name.len = value[i].len - 5; name.data = value[i].data + 5; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"rcs_zone\" must have \"size\" parameter"); return NGX_CONF_ERROR; } if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"rcs_zone\" must have \"name\" parameter"); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_tfs_rc_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_tfs_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } shm_zone->init = ngx_http_tfs_rc_server_init_zone; shm_zone->data = ctx; tu->rc_ctx = ctx; tu->rcs_zone_name = name; return NGX_CONF_OK; }
static char * ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { syslog(LOG_INFO, "[%s:%s:%d]", __FILE__, __func__, __LINE__); u_char *p; ssize_t size; ngx_str_t *value, name, s; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_limit_conn_ctx_t *ctx; value = cf->args->elts; ctx = NULL; size = 0; name.len = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } name.len = p - name.data; s.data = p + 1; s.len = value[i].data + value[i].len - s.data; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } if (value[i].data[0] == '$') { value[i].len--; value[i].data++; ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->index = ngx_http_get_variable_index(cf, &value[i]); if (ctx->index == NGX_ERROR) { return NGX_CONF_ERROR; } ctx->var = value[i]; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (ctx == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no variable is defined for %V \"%V\"", &cmd->name, &name); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_limit_conn_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound to variable \"%V\"", &cmd->name, &name, &ctx->var); return NGX_CONF_ERROR; } shm_zone->init = ngx_http_limit_conn_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_tcp_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_tcp_ssl_srv_conf_t *sscf = conf; size_t len; ngx_str_t *value, name, size; ngx_int_t n; ngx_uint_t i, j; value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "off") == 0) { sscf->builtin_session_cache = NGX_SSL_NO_SCACHE; continue; } if (ngx_strcmp(value[i].data, "none") == 0) { sscf->builtin_session_cache = NGX_SSL_NONE_SCACHE; continue; } if (ngx_strcmp(value[i].data, "builtin") == 0) { sscf->builtin_session_cache = NGX_SSL_DFLT_BUILTIN_SCACHE; continue; } if (value[i].len > sizeof("builtin:") - 1 && ngx_strncmp(value[i].data, "builtin:", sizeof("builtin:") - 1) == 0) { n = ngx_atoi(value[i].data + sizeof("builtin:") - 1, value[i].len - (sizeof("builtin:") - 1)); if (n == NGX_ERROR) { goto invalid; } sscf->builtin_session_cache = n; continue; } if (value[i].len > sizeof("shared:") - 1 && ngx_strncmp(value[i].data, "shared:", sizeof("shared:") - 1) == 0) { len = 0; for (j = sizeof("shared:") - 1; j < value[i].len; j++) { if (value[i].data[j] == ':') { value[i].data[j] = '\0'; break; } len++; } if (len == 0) { goto invalid; } name.len = len; name.data = value[i].data + sizeof("shared:") - 1; size.len = value[i].len - j - 1; size.data = name.data + len + 1; n = ngx_parse_size(&size); if (n == NGX_ERROR) { goto invalid; } if (n < (ngx_int_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "session cache \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } sscf->shm_zone = ngx_shared_memory_add(cf, &name, n, &ngx_tcp_ssl_module); if (sscf->shm_zone == NULL) { return NGX_CONF_ERROR; } //#if defined(nginx_version) && nginx_version >= 1000007 sscf->shm_zone->init = ngx_ssl_session_cache_init; //#endif continue; } goto invalid; } if (sscf->shm_zone && sscf->builtin_session_cache == NGX_CONF_UNSET) { sscf->builtin_session_cache = NGX_SSL_NO_BUILTIN_SCACHE; } return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid session cache \"%V\"", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; size_t len; ssize_t size; ngx_str_t *value, name, s; ngx_int_t rate, scale; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_ctx_t *ctx; ngx_http_compile_complex_value_t ccv; #if (T_LIMIT_REQ_RATE_VAR) ngx_http_limit_req_variable_t rate_var; #endif value = cf->args->elts; ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } #if (T_LIMIT_REQ) { u_char *p; size_t len; ngx_str_t v1; len = 0; for (i = 1; i < cf->args->nelts; i++) { if (i == 1 || value[i].data[0] == '$') { len += value[i].len; } break; } p = ngx_palloc(cf->pool, len); if (p == NULL) { return NGX_CONF_ERROR; } v1.len = len; v1.data = p; for (i = 1; i < cf->args->nelts; i++) { if (i == 1 || value[i].data[0] == '$') { p = ngx_cpymem(p, value[i].data, value[i].len); } break; } ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &v1; ccv.complex_value = &ctx->key; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } } #else ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[1]; ccv.complex_value = &ctx->key; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } #endif size = 0; rate = 1; scale = 1; name.len = 0; #if (T_LIMIT_REQ_RATE_VAR) memset(&rate_var, 0x0, sizeof(rate_var)); #endif for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } name.len = p - name.data; s.data = p + 1; s.len = value[i].data + value[i].len - s.data; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { #if (T_LIMIT_REQ_RATE_VAR) if (value[i].data[5] == '$') { value[i].data += 6; value[i].len -= 6; rate_var.index = ngx_http_get_variable_index(cf, &value[i]); if (rate_var.index == NGX_ERROR) { return NGX_CONF_ERROR; } rate_var.var = value[i]; continue; } #endif len = value[i].len; p = value[i].data + len - 3; if (ngx_strncmp(p, "r/s", 3) == 0) { scale = 1; len -= 3; } else if (ngx_strncmp(p, "r/m", 3) == 0) { scale = 60; len -= 3; } rate = ngx_atoi(value[i].data + 5, len - 5); if (rate <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } #if (T_LIMIT_REQ) if (value[i].data[0] == '$') { continue; } #endif ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } ctx->rate = rate * 1000 / scale; #if (T_LIMIT_REQ_RATE_VAR) ctx->rate_var = rate_var; #endif shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound to key \"%V\"", &cmd->name, &name, &ctx->key.value); return NGX_CONF_ERROR; } shm_zone->init = ngx_http_limit_req_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; ngx_int_t burst; ngx_str_t *value, s; ngx_uint_t i, nodelay; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_limit_t *limit, *limits; value = cf->args->elts; shm_zone = NULL; burst = 0; nodelay = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strcmp(value[i].data, "nodelay") == 0) { nodelay = 1; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", &shm_zone->shm.name); return NGX_CONF_ERROR; } limits = lrcf->limits.elts; if (limits == NULL) { if (ngx_array_init(&lrcf->limits, cf->pool, 1, sizeof(ngx_http_limit_req_limit_t)) != NGX_OK) { return NGX_CONF_ERROR; } } for (i = 0; i < lrcf->limits.nelts; i++) { if (shm_zone == limits[i].shm_zone) { return "is duplicate"; } } limit = ngx_array_push(&lrcf->limits); if (limit == NULL) { return NGX_CONF_ERROR; } limit->shm_zone = shm_zone; limit->burst = burst * 1000; limit->nodelay = nodelay; return NGX_CONF_OK; }
/* * Q: 怎样找到函数中创建的 ngx_http_file_cache_t? * A: 1. 可以通过path中的data字段找到此cache * 2. 通过共享内存区 shm_zone.data 字段找到 */ char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; // cache磁盘空间大小 u_char *last, *p; time_t inactive; // cache不活跃的时间 ssize_t size; // 共享内存区的大小(必须大于8k) ngx_str_t s, name, *value; // name: 共享内存区的名称 ngx_int_t loader_files; ngx_msec_t loader_sleep, loader_threshold; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; // 不活跃时间默认是10分钟 loader_files = 100; loader_sleep = 50; loader_threshold = 200; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; // cache路径, 如果以"/"结尾将被自动去掉 cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } // 获取cache的完整路径 if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { // 设置子目录数和子目录的文件名长度 if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } // 设置cache的共享存储区 if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; // 共享内存区的名字 p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; // 共享内存区的名字长度 p++; s.len = value[i].data + value[i].len - p; // 共享内存区的大小 s.data = p; size = ngx_parse_size(&s); // 申请的共享内存区大小(必须大于8K) if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } // 设置cache不活跃的时间 if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive == (time_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // 设置缓存磁盘空间大小 max_size if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_files if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) { loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13); if (loader_files == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_files value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_sleep if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) { s.len = value[i].len - 13; s.data = value[i].data + 13; loader_sleep = ngx_parse_time(&s, 0); if (loader_sleep == (ngx_msec_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_sleep value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } // loader_threshold if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) { s.len = value[i].len - 17; s.data = value[i].data + 17; loader_threshold = ngx_parse_time(&s, 0); if (loader_threshold == (ngx_msec_t) NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_threshold value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } // for if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; // 设置 ngx_http_file_cache_t 结构 cache->path->conf_file = cf->conf_file->file.name.data; cache->path->line = cf->conf_file->line; cache->loader_files = loader_files; cache->loader_sleep = loader_sleep; cache->loader_threshold = loader_threshold; // 添加目录到系统管理目录表中 if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } // 添加共享内存到系统管理表中 cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } /* e.g. "proxy_cache" 与 "proxy_cache_path" 这两个指令的使用是有顺序的, "proxy_cache" 指令仅初始化共享内存信息,cache->shm_zone->data字段设置为NULL, 如果data字段被设置,说明重复定义了共享内存区 */ if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }
static char * ngx_lua_autorun(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_lua_autorun_conf_t *lacf = conf; ngx_str_t *value, str; ngx_uint_t i; ngx_log_debug0(NGX_LOG_DEBUG_CORE, cf->log, 0, "lua autorun"); if (lacf->name.data != NULL) { return "is duplicate"; } value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "name=", 5) == 0) { lacf->name.len = value[i].len - 5; lacf->name.data = value[i].data + 5; continue; } if (ngx_strncmp(value[i].data, "size=", 5) == 0) { str.len = value[i].len - 5; str.data = value[i].data + 5; lacf->size = ngx_parse_size(&str); if (lacf->size == (size_t) NGX_ERROR) { goto invalid; } continue; } goto invalid; } if (lacf->name.data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the directive \"lua_autorun\" must be specified"); return NGX_CONF_ERROR; } ngx_conf_init_size_value(lacf->size, 1024 * 1024 * 1); lacf->zone = ngx_shared_memory_add(cf, &lacf->name, lacf->size, &ngx_lua_autorun_module); if (lacf->zone == NULL) { return NGX_CONF_ERROR; } if (lacf->zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate lua autorun name \"%V\"", &lacf->name); return NGX_CONF_ERROR; } lacf->zone->init = ngx_lua_autorun_init; lacf->zone->data = lacf; return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\" in lua_autorun", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_btt(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_btt_conf_t *bcf = conf; ngx_str_t *value, str; ngx_uint_t i; if (bcf->name.data != NULL) { return "is duplicate"; } value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "name=", 5) == 0) { bcf->name.len = value[i].len - 5; bcf->name.data = value[i].data + 5; continue; } if (ngx_strncmp(value[i].data, "size=", 5) == 0) { str.len = value[i].len - 5; str.data = value[i].data + 5; bcf->size = ngx_parse_size(&str); if (bcf->size == (size_t) NGX_ERROR) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "expire=", 7) == 0) { str.len = value[i].len - 7; str.data = value[i].data + 7; bcf->expire = ngx_parse_time(&str, 1); if (bcf->expire == NGX_ERROR) { goto invalid; } continue; } if (ngx_strncmp(value[i].data, "interval=", 9) == 0) { str.len = value[i].len - 9; str.data = value[i].data + 9; bcf->interval = ngx_parse_time(&str, 1); if (bcf->interval == NGX_ERROR) { goto invalid; } continue; } goto invalid; } if (bcf->name.data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the directive \"btt\" must be specified"); return NGX_CONF_ERROR; } ngx_conf_init_size_value(bcf->size, 1024 * 1024 * 10); ngx_conf_init_value(bcf->expire, 60); ngx_conf_init_value(bcf->interval, 30); bcf->zone = ngx_shared_memory_add(cf, &bcf->name, bcf->size, &ngx_lua_btt_module); if (bcf->zone == NULL) { return NGX_CONF_ERROR; } if (bcf->zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate btt name \"%V\"", &bcf->name); return NGX_CONF_ERROR; } bcf->zone->init = ngx_btt_init; bcf->zone->data = bcf; return NGX_CONF_OK; invalid: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\" in btt", &value[i]); return NGX_CONF_ERROR; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; ngx_int_t burst; ngx_str_t *value, s, forbid_action; ngx_uint_t i, nodelay; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_limit_t *limit_req; value = cf->args->elts; if (cf->args->nelts == 2) { if (ngx_strncmp(value[1].data, "off", 3) == 0) { lrcf->enable = 0; return NGX_CONF_OK; } } lrcf->enable = 1; shm_zone = NULL; burst = 0; nodelay = 0; ngx_str_null(&forbid_action); for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "forbid_action=", 14) == 0) { s.len = value[i].len - 14; s.data = value[i].data + 14; if (s.len < 2 || (s.data[0] != '@' && s.data[0] != '/')) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid forbid_action \"%V\"", &value[i]); return NGX_CONF_ERROR; } forbid_action = s; continue; } if (ngx_strcmp(value[i].data, "nodelay") == 0) { nodelay = 1; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } /* if (shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", &shm_zone->shm.name); return NGX_CONF_ERROR; } */ if (lrcf->rules == NULL) { lrcf->rules = ngx_array_create(cf->pool, 5, sizeof(ngx_http_limit_req_limit_t)); if (lrcf->rules == NULL) { return NGX_CONF_ERROR; } } limit_req = lrcf->rules->elts; for (i = 0; i < lrcf->rules->nelts; i++) { if (shm_zone == limit_req[i].shm_zone) { return "is duplicate"; } } limit_req = ngx_array_push(lrcf->rules); if (limit_req == NULL) { return NGX_CONF_ERROR; } ngx_memzero(limit_req, sizeof(ngx_http_limit_req_limit_t)); limit_req->shm_zone = shm_zone; limit_req->burst = burst * 1000; limit_req->nodelay = nodelay; limit_req->forbid_action = forbid_action; return NGX_CONF_OK; }
static char * ngx_conf_limit_tcp(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_limit_tcp_conf_t *ltcf = conf; u_char *p; size_t len; ssize_t size; ngx_int_t burst, rate, scale, concurrent; ngx_str_t *value, s, name; ngx_url_t u; ngx_uint_t i, j, nodelay; ngx_array_t *ls; ngx_shm_zone_t *shm_zone; ngx_limit_tcp_ctx_t *ctx; ngx_limit_tcp_addr_t *addr, **paddr, **taddr; burst = 0; nodelay = 0; concurrent = 0; rate = 0; scale = 1; size = 1024 * 1024 * 2; ngx_str_set(&name, "limit_tcp_shm"); ls = ngx_array_create(cf->pool, 1, sizeof(ngx_limit_tcp_addr_t)); if (ls == NULL) { return NGX_CONF_ERROR; } value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "name=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid size \"%V\"", &value[i]); return NGX_CONF_ERROR; } else if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { len = value[i].len; p = value[i].data + len - 3; if (ngx_strncmp(p, "r/s", 3) == 0) { scale = 1; len -= 3; } else if (ngx_strncmp(p, "r/m", 3) == 0) { scale = 60; len -= 3; } rate = ngx_atoi(value[i].data + 5, len - 5); if (rate <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } } else if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } else if (ngx_strncmp(value[i].data, "concurrent=", 11) == 0) { concurrent = ngx_atoi(value[i].data + 11, value[i].len - 11); if (concurrent <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid concurrent \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } else if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) { nodelay = 1; continue; } else { /* ip:port */ ngx_memzero(&u, sizeof(ngx_url_t)); u.url = value[i]; u.listen = 1; u.default_port = 80; if (ngx_parse_url(cf->pool, &u) != NGX_OK) { if (u.err) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s in \"%V\" of the \"limit_tcp\"" " directive", u.err, &u.url); } return NGX_CONF_ERROR; } addr = ngx_array_push(ls); if (addr == NULL) { return NGX_CONF_ERROR; } ngx_memzero(addr, sizeof(ngx_limit_tcp_addr_t)); ngx_memcpy(&addr->sockaddr, u.sockaddr, u.socklen); addr->socklen = u.socklen; addr->addr_text = u.url; } } if (concurrent == 0 && rate == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "you need to set concurrent or rate"); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_limit_tcp_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" is already bound", &name); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_limit_tcp_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->nodelay = nodelay; ctx->concurrent = concurrent; ctx->rate = rate * 1000 / scale; ctx->burst = burst * 1000; ctx->shm_size = size; shm_zone->init = ngx_limit_tcp_init_zone; shm_zone->data = ctx; paddr = ltcf->lsocks.elts; addr = ls->elts; for (i = 0; i < ls->nelts; i++) { for (j = 0; j < ltcf->lsocks.nelts; j++) { if (addr[i].addr_text.len != paddr[j]->addr_text.len) { continue; } if (ngx_strncmp(addr[i].addr_text.data, paddr[j]->addr_text.data, addr[i].addr_text.len) != 0) { continue; } break; } if (j != ltcf->lsocks.nelts) { continue; } taddr = ngx_array_push(<cf->lsocks); if (taddr == NULL) { return NGX_CONF_ERROR; } addr[i].ctx = ctx; *taddr = &addr[i]; } ltcf->enable = 1; return NGX_CONF_OK; }
static char * ngx_http_limit_access_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; size_t size, len; ngx_str_t *value, name, s, variable; ngx_int_t number, index; ngx_uint_t i; ngx_uint_t type; ngx_shm_zone_t *shm_zone; ngx_http_limit_access_ctx_t *ctx; value = cf->args->elts; number = NGX_HASH_LARGE_HSIZE; name.len = 0; size = 0; type = HASH_IP; index = NGX_CONF_UNSET; variable.len = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "bucket_number=", 14) == 0) { len = value[i].len - 14; p = value[i].data + 14; number = ngx_atoi(p, len); if (number <= NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid number \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "type=", 5) == 0) { len = value[i].len - 5; p = value[i].data + 5; if (ngx_strncmp(p, "ip", len) == 0) { type = HASH_IP; } else if (p[0] == '$') { type = HASH_VARIABLE; variable.data = p + 1; variable.len = len - 1; index = ngx_http_get_variable_index(cf, &variable); if (index == NGX_ERROR) { return NGX_CONF_ERROR; } } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid type \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_limit_access_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "limit_access_zone \"%V\" is already used.", &value[1]); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_access_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->type = type; ctx->bucket_number = number; if (type == HASH_VARIABLE) { ctx->index = index; ctx->var = variable; } shm_zone->init = ngx_http_limit_access_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_vhost_traffic_status_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ssize_t size; u_char *p; ngx_uint_t i; ngx_str_t *value, name, s; ngx_shm_zone_t *shm_zone; ngx_http_vhost_traffic_status_ctx_t *ctx; value = cf->args->elts; ctx = ngx_http_conf_get_module_main_conf(cf, ngx_http_vhost_traffic_status_module); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->enable = 1; ngx_str_set(&name, NGX_HTTP_VHOST_TRAFFIC_STATUS_DEFAULT_SHM_NAME); size = NGX_HTTP_VHOST_TRAFFIC_STATUS_DEFAULT_SHM_SIZE; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "shared:", 7) == 0) { name.data = value[i].data + 7; p = (u_char *) ngx_strchr(name.data, ':'); if (p == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid shared size \"%V\"", &value[i]); return NGX_CONF_ERROR; } name.len = p - name.data; s.data = p + 1; s.len = value[i].data + value[i].len - s.data; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid shared size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "shared \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_vhost_traffic_status_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "vhost_traffic_status: \"%V\" is already bound to key", &name); return NGX_CONF_ERROR; } ctx->shm_name = name; ctx->shm_size = size; shm_zone->init = ngx_http_vhost_traffic_status_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; ngx_int_t burst; ngx_str_t *value, s, forbid_action; ngx_uint_t i, nodelay; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_limit_t *limit, *limits; ngx_http_limit_req_variable_t condition; value = cf->args->elts; shm_zone = NULL; burst = 0; nodelay = 0; condition.index = -1; ngx_str_null(&condition.var); ngx_str_null(&forbid_action); for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strcmp(value[i].data, "nodelay") == 0) { nodelay = 1; continue; } if (ngx_strncmp(value[i].data, "forbid_action=", 14) == 0) { s.len = value[i].len - 14; s.data = value[i].data + 14; if (s.len < 2 || (s.data[0] != '@' && s.data[0] != '/')) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid forbid_action \"%V\"", &value[i]); return NGX_CONF_ERROR; } forbid_action = s; continue; } if (ngx_strncmp(value[i].data, "condition=", 10) == 0) { s.len = value[i].len - 10; s.data = value[i].data + 10; if (s.len < 2 || s.data[0] != '$') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid condition \"%V\"", &value[i]); return NGX_CONF_ERROR; } s.len--; s.data++; condition.index = ngx_http_get_variable_index(cf, &s); if (condition.index == NGX_ERROR) { return NGX_CONF_ERROR; } condition.var = s; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", &shm_zone->shm.name); return NGX_CONF_ERROR; } limits = lrcf->limits.elts; if (limits == NULL) { if (ngx_array_init(&lrcf->limits, cf->pool, 1, sizeof(ngx_http_limit_req_limit_t)) != NGX_OK) { return NGX_CONF_ERROR; } } for (i = 0; i < lrcf->limits.nelts; i++) { if (shm_zone == limits[i].shm_zone) { return "is duplicate"; } } limit = ngx_array_push(&lrcf->limits); if (limit == NULL) { return NGX_CONF_ERROR; } limit->shm_zone = shm_zone; limit->burst = burst * 1000; limit->nodelay = nodelay; limit->forbid_action = forbid_action; limit->condition = condition; return NGX_CONF_OK; }
char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; u_char *last, *p; time_t inactive; ssize_t size; ngx_str_t s, name, *value; ngx_int_t loader_files, loader_sleep, loader_threshold; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; loader_files = 100; loader_sleep = 50; loader_threshold = 200; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; //proxy_cache_path /data/proxy_cache_dir levels=1:2 keys_zone=STATIC:200m inactive=1d max_size=30g; p = (u_char *) ngx_strchr(name.data, ':');//find the if (p) { *p = '\0'; name.len = p - name.data; //the shared dir name!!! p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); //The share memory size!!! if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) { loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13); if (loader_files == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_files value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_sleep=", 13) == 0) { s.len = value[i].len - 13; s.data = value[i].data + 13; loader_sleep = ngx_parse_time(&s, 0); if (loader_sleep < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_sleep value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "loader_threshold=", 17) == 0) { s.len = value[i].len - 17; s.data = value[i].data + 17; loader_threshold = ngx_parse_time(&s, 0); if (loader_threshold < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid loader_threshold value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; cache->path->conf_file = cf->conf_file->file.name.data; cache->path->line = cf->conf_file->line; cache->loader_files = loader_files; cache->loader_sleep = (ngx_msec_t) loader_sleep; cache->loader_threshold = (ngx_msec_t) loader_threshold; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } //the size is the configed size we set in the proxy_cache_path () !!! //Here,We create a shm_zone(share memory!!) cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }
static char * ngx_http_reqstat(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_str_t *value; ngx_uint_t i, j; ngx_shm_zone_t *shm_zone, **z; ngx_http_reqstat_conf_t *smcf; ngx_http_reqstat_conf_t *slcf = conf; value = cf->args->elts; smcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_reqstat_module); if (slcf->monitor != NGX_CONF_UNSET_PTR) { return "is duplicate"; } if (smcf->monitor == NULL) { smcf->monitor = ngx_array_create(cf->pool, cf->args->nelts - 1, sizeof(ngx_shm_zone_t *)); if (smcf->monitor == NULL) { return NGX_CONF_ERROR; } } slcf->monitor = ngx_array_create(cf->pool, cf->args->nelts - 1, sizeof(ngx_shm_zone_t *)); if (slcf->monitor == NULL) { return NGX_CONF_ERROR; } for (i = 1; i < cf->args->nelts; i++) { shm_zone = ngx_shared_memory_add(cf, &value[i], 0, &ngx_http_reqstat_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } z = ngx_array_push(slcf->monitor); *z = shm_zone; z = smcf->monitor->elts; for (j = 0; j < smcf->monitor->nelts; j++) { if (!ngx_strcmp(value[i].data, z[j]->shm.name.data)) { break; } } if (j == smcf->monitor->nelts) { z = ngx_array_push(smcf->monitor); if (z == NULL) { return NGX_CONF_ERROR; } *z = shm_zone; } } ngx_http_log_flow = ngx_http_reqstat_log_flow; return NGX_CONF_OK; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; char *rv; ngx_int_t burst; ngx_str_t *value, s; ngx_uint_t i; ngx_http_limit_req_t *limit_req; if (lrcf->rules == NULL) { lrcf->rules = ngx_array_create(cf->pool, 5, sizeof(ngx_http_limit_req_t)); if (lrcf->rules == NULL) { return NGX_CONF_ERROR; } } limit_req = ngx_array_push(lrcf->rules); if (limit_req == NULL) { return NGX_CONF_ERROR; } ngx_memzero(limit_req, sizeof(ngx_http_limit_req_t)); value = cf->args->elts; if (cf->args->nelts == 2) { rv = ngx_conf_set_flag_slot(cf, cmd, lrcf); return rv; } burst = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; limit_req->shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (limit_req->shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "forbid_action=", 14) == 0) { s.len = value[i].len - 14; s.data = value[i].data + 14; if (s.len < 2 || (s.data[0] != '@' && s.data[0] != '/')) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid forbid_action \"%V\"", &value[i]); return NGX_CONF_ERROR; } limit_req->forbid_action = s; continue; } if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) { limit_req->nodelay = 1; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (limit_req->shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (limit_req->shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", &limit_req->shm_zone->shm.name); return NGX_CONF_ERROR; } limit_req->burst = burst * 1000; if (lrcf->enable == NGX_CONF_UNSET) { lrcf->enable = 1; } return NGX_CONF_OK; }
char * ngx_http_lua_shared_dict(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_lua_main_conf_t *lmcf = conf; ngx_str_t *value, name; ngx_shm_zone_t *zone; ngx_shm_zone_t **zp; ngx_http_lua_shdict_ctx_t *ctx; ssize_t size; if (lmcf->shm_zones == NULL) { lmcf->shm_zones = ngx_palloc(cf->pool, sizeof(ngx_array_t)); if (lmcf->shm_zones == NULL) { return NGX_CONF_ERROR; } if (ngx_array_init(lmcf->shm_zones, cf->pool, 2, sizeof(ngx_shm_zone_t *)) != NGX_OK) { return NGX_CONF_ERROR; } } value = cf->args->elts; ctx = NULL; if (value[1].len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid lua shared dict name \"%V\"", &value[1]); return NGX_CONF_ERROR; } name = value[1]; size = ngx_parse_size(&value[2]); if (size <= 8191) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid lua shared dict size \"%V\"", &value[2]); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_lua_shdict_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->name = name; ctx->main_conf = lmcf; ctx->log = &cf->cycle->new_log; ctx->cycle = cf->cycle; zone = ngx_shared_memory_add(cf, &name, (size_t) size, &ngx_http_lua_module); if (zone == NULL) { return NGX_CONF_ERROR; } if (zone->data) { ctx = zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "lua_shared_dict \"%V\" is already defined as " "\"%V\"", &name, &ctx->name); return NGX_CONF_ERROR; } zone->init = ngx_http_lua_shdict_init_zone; zone->data = ctx; zp = ngx_array_push(lmcf->shm_zones); if (zp == NULL) { return NGX_CONF_ERROR; } *zp = zone; lmcf->requires_shm = 1; return NGX_CONF_OK; }
static char * ngx_stream_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; ssize_t size; ngx_str_t *value, name, s; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_stream_limit_conn_ctx_t *ctx; value = cf->args->elts; ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_limit_conn_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } size = 0; name.len = 0; for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } name.len = p - name.data; s.data = p + 1; s.len = value[i].data + value[i].len - s.data; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_stream_limit_conn_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound to key " "\"$binary_remote_addr\"", &cmd->name, &name); return NGX_CONF_ERROR; } if (ngx_strcmp(value[1].data, "$binary_remote_addr") != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unsupported key \"%V\", use " "$binary_remote_addr", &value[1]); return NGX_CONF_ERROR; } shm_zone->init = ngx_stream_limit_conn_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
char * ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { off_t max_size; u_char *last, *p; time_t inactive; ssize_t size; ngx_str_t s, name, *value; ngx_uint_t i, n; ngx_http_file_cache_t *cache; cache = ngx_pcalloc(cf->pool, sizeof(ngx_http_file_cache_t)); if (cache == NULL) { return NGX_CONF_ERROR; } cache->path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t)); if (cache->path == NULL) { return NGX_CONF_ERROR; } inactive = 600; name.len = 0; size = 0; max_size = NGX_MAX_OFF_T_VALUE; value = cf->args->elts; cache->path->name = value[1]; if (cache->path->name.data[cache->path->name.len - 1] == '/') { cache->path->name.len--; } if (ngx_conf_full_name(cf->cycle, &cache->path->name, 0) != NGX_OK) { return NGX_CONF_ERROR; } for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "levels=", 7) == 0) { p = value[i].data + 7; last = value[i].data + value[i].len; for (n = 0; n < 3 && p < last; n++) { if (*p > '0' && *p < '3') { cache->path->level[n] = *p++ - '0'; cache->path->len += cache->path->level[n] + 1; if (p == last) { break; } if (*p++ == ':' && n < 2 && p != last) { continue; } goto invalid_levels; } goto invalid_levels; } if (cache->path->len < 10 + 3) { continue; } invalid_levels: ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid \"levels\" \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "keys_zone=", 10) == 0) { name.data = value[i].data + 10; p = (u_char *) ngx_strchr(name.data, ':'); if (p) { *p = '\0'; name.len = p - name.data; p++; s.len = value[i].data + value[i].len - p; s.data = p; size = ngx_parse_size(&s); if (size > 8191) { continue; } } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid keys zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (ngx_strncmp(value[i].data, "inactive=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; inactive = ngx_parse_time(&s, 1); if (inactive < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid inactive value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "max_size=", 9) == 0) { s.len = value[i].len - 9; s.data = value[i].data + 9; max_size = ngx_parse_offset(&s); if (max_size < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid max_size value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0 || size == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"keys_zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } cache->path->manager = ngx_http_file_cache_manager; cache->path->loader = ngx_http_file_cache_loader; cache->path->data = cache; if (ngx_add_path(cf, &cache->path) != NGX_OK) { return NGX_CONF_ERROR; } cache->shm_zone = ngx_shared_memory_add(cf, &name, size, cmd->post); if (cache->shm_zone == NULL) { return NGX_CONF_ERROR; } if (cache->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate zone \"%V\"", &name); return NGX_CONF_ERROR; } cache->shm_zone->init = ngx_http_file_cache_init; cache->shm_zone->data = cache; cache->inactive = inactive; cache->max_size = max_size; return NGX_CONF_OK; }
static char * ngx_http_tfs_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_int_t enable; ngx_str_t *value, s; ngx_http_tfs_main_conf_t *tmcf; ngx_http_tfs_srv_conf_t *tscf; ngx_http_core_loc_conf_t *clcf; value = cf->args->elts; if (ngx_strncmp(value[1].data, "enable=", 7) == 0) { s.len = value[1].len - 7; s.data = value[1].data + 7; enable = ngx_atoi(s.data, s.len); if (!enable) { return NGX_CONF_OK; } } clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); tscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_tfs_module); tmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_tfs_module); clcf->handler = ngx_http_tfs_handler; if (clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; } if (tmcf->enable_rcs == NGX_CONF_UNSET) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign enable rcs, use directives \"tfs_enable_rcs\" "); return NGX_CONF_ERROR; } if (tmcf->enable_rcs) { if (tscf->local_addr_text[0] == '\0') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign net device name, use directives \"tfs_net_device\" "); return NGX_CONF_ERROR; } s.data = (u_char *) NGX_HTTP_TFS_RCS_ZONE_NAME; s.len = sizeof(NGX_HTTP_TFS_RCS_ZONE_NAME) - 1; tmcf->rcs_shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_tfs_module); if (tmcf->rcs_shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign rcs shm zone, use directives \"tfs_rcs_zone\" "); return NGX_CONF_ERROR; } } if (tmcf->local_block_cache_ctx != NULL) { s.data = (u_char *) NGX_HTTP_TFS_BLOCK_CACHE_ZONE_NAME; s.len = sizeof(NGX_HTTP_TFS_BLOCK_CACHE_ZONE_NAME) - 1; tmcf->block_cache_shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_tfs_module); if (tmcf->block_cache_shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign block cache shm zone,"\ "use directives \"tfs_block_cache_zone\" "); return NGX_CONF_ERROR; } } return NGX_CONF_OK; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lrcf = conf; ngx_int_t burst, delay; ngx_str_t *value, s; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_limit_t *limit, *limits; #if (T_LIMIT_REQ) ngx_str_t forbid_action; #endif value = cf->args->elts; #if (T_LIMIT_REQ) if (cf->args->nelts == 2) { if (ngx_strncmp(value[1].data, "off", 3) == 0) { lrcf->enable = 0; return NGX_CONF_OK; } } lrcf->enable = 1; ngx_str_null(&forbid_action); #endif shm_zone = NULL; burst = 0; delay = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "delay=", 6) == 0) { delay = ngx_atoi(value[i].data + 6, value[i].len - 6); if (delay <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid delay value \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strcmp(value[i].data, "nodelay") == 0) { delay = NGX_MAX_INT_T_VALUE / 1000; continue; } #if (T_LIMIT_REQ) if (ngx_strncmp(value[i].data, "forbid_action=", 14) == 0) { s.len = value[i].len - 14; s.data = value[i].data + 14; if (s.len < 2 || (s.data[0] != '@' && s.data[0] != '/')) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid forbid_action \"%V\"", &value[i]); return NGX_CONF_ERROR; } forbid_action = s; continue; } #endif ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } limits = lrcf->limits.elts; if (limits == NULL) { if (ngx_array_init(&lrcf->limits, cf->pool, 1, sizeof(ngx_http_limit_req_limit_t)) != NGX_OK) { return NGX_CONF_ERROR; } } for (i = 0; i < lrcf->limits.nelts; i++) { if (shm_zone == limits[i].shm_zone) { return "is duplicate"; } } limit = ngx_array_push(&lrcf->limits); if (limit == NULL) { return NGX_CONF_ERROR; } limit->shm_zone = shm_zone; limit->burst = burst * 1000; limit->delay = delay * 1000; #if (T_LIMIT_REQ) limit->forbid_action = forbid_action; #endif return NGX_CONF_OK; }
shmem_t *shm; shm_size = ngx_align(shm_size, ngx_pagesize); if (shm_size < 8 * ngx_pagesize) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "The push_max_reserved_memory value must be at least %udKiB", (8 * ngx_pagesize) >> 10); shm_size = 8 * ngx_pagesize; } /* if(nchan_shm_zone && nchan_shm_zone->shm.size != shm_size) { ngx_conf_log_error(NGX_LOG_WARN, cf, 0, "Cannot change memory area size without restart, ignoring change"); } */ ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "Using %udKiB of shared memory for nchan", shm_size >> 10); shm = ngx_alloc(sizeof(*shm), ngx_cycle->log); zone = ngx_shared_memory_add(cf, name, shm_size, &nchan_module); if (zone == NULL || shm == NULL) { return NULL; } shm->zone = zone; zone->init = init; zone->data = (void *) 1; return shm; } ngx_int_t shm_init(shmem_t *shm) { #if (DEBUG_SHM_ALLOC == 1) ngx_slab_pool_t *shpool = SHPOOL(shm); ngx_log_error(NGX_LOG_WARN, ngx_cycle->log, 0, "nchan_shpool start %p size %i", shpool->start, (u_char *)shpool->end - (u_char *)shpool->start); #endif
static char * ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { u_char *p; size_t len; ssize_t size; ngx_str_t *value, name, s; ngx_int_t rate, scale; ngx_uint_t i; ngx_shm_zone_t *shm_zone; ngx_http_limit_req_ctx_t *ctx; value = cf->args->elts; ctx = NULL; size = 0; rate = 1; scale = 1; name.len = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { name.data = value[i].data + 5; p = (u_char *) ngx_strchr(name.data, ':'); if (p == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } name.len = p - name.data; s.data = p + 1; s.len = value[i].data + value[i].len - s.data; size = ngx_parse_size(&s); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { len = value[i].len; p = value[i].data + len - 3; if (ngx_strncmp(p, "r/s", 3) == 0) { scale = 1; len -= 3; } else if (ngx_strncmp(p, "r/m", 3) == 0) { scale = 60; len -= 3; } rate = ngx_atoi(value[i].data + 5, len - 5); if (rate <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (value[i].data[0] == '$') { value[i].len--; value[i].data++; ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->index = ngx_http_get_variable_index(cf, &value[i]); if (ctx->index == NGX_ERROR) { return NGX_CONF_ERROR; } ctx->var = value[i]; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (name.len == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (ctx == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "no variable is defined for %V \"%V\"", &cmd->name, &name); return NGX_CONF_ERROR; } ctx->rate = rate * 1000 / scale; shm_zone = ngx_shared_memory_add(cf, &name, size, &ngx_http_limit_req_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound to variable \"%V\"", &cmd->name, &name, &ctx->var); return NGX_CONF_ERROR; } shm_zone->init = ngx_http_limit_req_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_http_limit_req_conf_t *lzcf = conf; ngx_int_t burst; ngx_str_t *value, s; ngx_uint_t i; if (lzcf->shm_zone) { return "is duplicate"; } value = cf->args->elts; burst = 0; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "zone=", 5) == 0) { s.len = value[i].len - 5; s.data = value[i].data + 5; lzcf->shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_limit_req_module); if (lzcf->shm_zone == NULL) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "burst=", 6) == 0) { burst = ngx_atoi(value[i].data + 6, value[i].len - 6); if (burst <= 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid burst rate \"%V\"", &value[i]); return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "nodelay", 7) == 0) { lzcf->nodelay = 1; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", &value[i]); return NGX_CONF_ERROR; } if (lzcf->shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"%V\" must have \"zone\" parameter", &cmd->name); return NGX_CONF_ERROR; } if (lzcf->shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", &lzcf->shm_zone->name); return NGX_CONF_ERROR; } lzcf->burst = burst * 1000; return NGX_CONF_OK; }
static char* ngx_http_sla_pool (ngx_conf_t* cf, ngx_command_t* cmd, void* conf) { ngx_uint_t i; ngx_str_t* value; ngx_int_t ival; ngx_uint_t* pval; size_t size; ngx_shm_zone_t* shm_zone; ngx_http_sla_pool_t* pool; ngx_http_sla_main_conf_t* config = conf; value = cf->args->elts; /* проверка off пула */ if (value[1].len == 3 && ngx_strncmp(value[1].data, "off", 3) == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invaid sla_pool name \"%V\"", &value[1]); return NGX_CONF_ERROR; } /* поиск среди имеющихся пулов */ pool = config->pools.elts; for (i = 0; i < config->pools.nelts; i++) { if (pool[i].name.len == value[1].len && ngx_strcmp(pool[i].name.data, value[1].data) == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "duplicate sla_pool name \"%V\"", &value[1]); return NGX_CONF_ERROR; } } /* инициализация нового пула */ pool = ngx_array_push(&config->pools); if (pool == NULL) { return NGX_CONF_ERROR; } /* имя пула */ pool->name.data = ngx_palloc(cf->pool, (value[1].len + 1) * sizeof(u_char)); if (pool->name.data == NULL) { return NGX_CONF_ERROR; } pool->name.len = value[1].len; ngx_memcpy(pool->name.data, value[1].data, value[1].len); pool->name.data[value[1].len] = 0; /* массивы */ if (ngx_array_init(&pool->http, cf->pool, NGX_HTTP_SLA_MAX_HTTP_LEN, sizeof(ngx_uint_t)) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_array_init(&pool->timings, cf->pool, NGX_HTTP_SLA_MAX_TIMINGS_LEN, sizeof(ngx_uint_t)) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_array_init(&pool->quantiles, cf->pool, NGX_HTTP_SLA_MAX_QUANTILES_LEN, sizeof(ngx_uint_t)) != NGX_OK) { return NGX_CONF_ERROR; } /* значения по умолчанию */ pool->shm_pool = NULL; pool->shm_ctx = NULL; pool->avg_window = 1600; pool->min_timing = 0; pool->generation = 0; /* установится при аллокации shm зоны */ /* парсинг параметров */ for (i = 2; i < cf->args->nelts; i++) { if (ngx_strncmp(value[i].data, "timings=", 8) == 0) { if (ngx_http_sla_parse_list(cf, &value[i], 8, &pool->timings, 0) != NGX_OK) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "http=", 5) == 0) { if (ngx_http_sla_parse_list(cf, &value[i], 5, &pool->http, 1) != NGX_OK) { return NGX_CONF_ERROR; } continue; } if (ngx_strncmp(value[i].data, "avg_window=", 11) == 0) { ival = ngx_atoi(&value[i].data[11], value[i].len - 11); if (ival == NGX_ERROR || ival < 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "incorrect avg_window value \"%V\"", &value[i]); return NGX_CONF_ERROR; } pool->avg_window = ival; continue; } if (ngx_strncmp(value[i].data, "min_timing=", 11) == 0) { ival = ngx_atoi(&value[i].data[11], value[i].len - 11); if (ival == NGX_ERROR || ival < 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "incorrect min_timing value \"%V\"", &value[i]); return NGX_CONF_ERROR; } pool->min_timing = ival; continue; } if (value[i].len == 7 && ngx_strncmp(value[i].data, "default", 7) == 0) { if (config->default_pool != NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "default sla_pool \"%V\" already defined", &config->default_pool->name); return NGX_CONF_ERROR; } config->default_pool = pool; continue; } ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\" for sla_pool", &value[i]); return NGX_CONF_ERROR; } /* заполнение параметрами по умолчанию */ if (pool->timings.nelts == 0) { pval = ngx_array_push_n(&pool->timings, 3); pval[0] = 300; pval[1] = 500; pval[2] = 2000; } if (pool->http.nelts == 0) { pval = ngx_array_push_n(&pool->http, 13); pval[0] = 200; /* OK */ pval[1] = 301; /* Moved Permanently */ pval[2] = 302; /* Moved Temporarily */ pval[3] = 304; /* Not Modified */ pval[4] = 400; /* Bad Request */ pval[5] = 401; /* Unauthorized */ pval[6] = 403; /* Forbidden */ pval[7] = 404; /* Not Found */ pval[8] = 499; /* Nginx special */ pval[9] = 500; /* Internal Server Error */ pval[10] = 502; /* Bad Gateway */ pval[11] = 503; /* Service Unavailable */ pval[12] = 504; /* Gateway Timeout */ } if (pool->quantiles.nelts == 0) { pval = ngx_array_push_n(&pool->quantiles, 7); pval[0] = 25; /* обязательный */ pval[1] = 50; pval[2] = 75; /* обязательный */ pval[3] = 90; pval[4] = 95; pval[5] = 98; pval[6] = 99; } /* заполнение "хвостов" для учета общего числа */ pval = ngx_array_push(&pool->timings); *pval = -1; pval = ngx_array_push(&pool->http); *pval = -1; /* проверка размеров */ if (pool->http.nelts > NGX_HTTP_SLA_MAX_HTTP_LEN) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "http list too long for sla_pool"); return NGX_CONF_ERROR; } if (pool->timings.nelts > NGX_HTTP_SLA_MAX_TIMINGS_LEN) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "timings list too long for sla_pool"); return NGX_CONF_ERROR; } /* создание зоны shred memory */ size = (sizeof(ngx_http_sla_pool_shm_t) * NGX_HTTP_SLA_MAX_COUNTERS_LEN / ngx_pagesize + 2) * ngx_pagesize; shm_zone = ngx_shared_memory_add(cf, &pool->name, size, &ngx_http_sla_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data != NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "sla_pool \"%V\" is already allocated", &pool->name); return NGX_CONF_ERROR; } shm_zone->data = pool; shm_zone->init = ngx_http_sla_init_zone; return NGX_CONF_OK; }
static char * ngx_http_reqstat_zone_add_indicator(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_int_t *i; ngx_str_t *value; ngx_uint_t j; ngx_shm_zone_t *shm_zone; ngx_http_reqstat_ctx_t *ctx; value = cf->args->elts; shm_zone = ngx_shared_memory_add(cf, &value[1], 0, &ngx_http_reqstat_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" should be defined first", &value[1]); return NGX_CONF_ERROR; } ctx = shm_zone->data; if (ctx->user_defined != NULL) { return "is duplicate"; } if (cf->args->nelts > NGX_HTTP_REQSTAT_SLOT + 2) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "too many user defined variables"); return NGX_CONF_ERROR; } ctx->user_defined = ngx_array_create(cf->pool, cf->args->nelts - 2, sizeof(ngx_int_t)); if (ctx->user_defined == NULL) { return NGX_CONF_ERROR; } for (j = 2; j < cf->args->nelts; j++) { if (value[j].data[0] == '$') { value[j].data++; value[j].len--; } i = ngx_array_push(ctx->user_defined); *i = ngx_http_get_variable_index(cf, &value[j]); if (*i == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "failed to obtain variable \"%V\"", &value[j]); return NGX_CONF_ERROR; } } return NGX_CONF_OK; }
static char * ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { syslog(LOG_INFO, "[%s:%s:%d]", __FILE__, __func__, __LINE__); ssize_t n; ngx_str_t *value; ngx_shm_zone_t *shm_zone; ngx_http_limit_conn_ctx_t *ctx; ngx_conf_deprecated(cf, &ngx_conf_deprecated_limit_zone, NULL); value = cf->args->elts; if (value[2].data[0] != '$') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid variable name \"%V\"", &value[2]); return NGX_CONF_ERROR; } value[2].len--; value[2].data++; ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } ctx->index = ngx_http_get_variable_index(cf, &value[2]); if (ctx->index == NGX_ERROR) { return NGX_CONF_ERROR; } ctx->var = value[2]; n = ngx_parse_size(&value[3]); if (n == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid size of limit_zone \"%V\"", &value[3]); return NGX_CONF_ERROR; } if (n < (ngx_int_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "limit_zone \"%V\" is too small", &value[1]); return NGX_CONF_ERROR; } shm_zone = ngx_shared_memory_add(cf, &value[1], n, &ngx_http_limit_conn_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "limit_zone \"%V\" is already bound to variable \"%V\"", &value[1], &ctx->var); return NGX_CONF_ERROR; } shm_zone->init = ngx_http_limit_conn_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_reqstat_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ssize_t size; ngx_str_t *value; ngx_shm_zone_t *shm_zone; ngx_http_reqstat_ctx_t *ctx; ngx_http_compile_complex_value_t ccv; value = cf->args->elts; size = ngx_parse_size(&value[3]); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid zone size \"%V\"", &value[3]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "zone \"%V\" is too small", &value[1]); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_reqstat_ctx_t)); if (ctx == NULL) { return NGX_CONF_ERROR; } if (ngx_http_script_variables_count(&value[2]) == 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the value \"%V\" is a constant", &value[2]); return NGX_CONF_ERROR; } ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[2]; ccv.complex_value = &ctx->value; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } ctx->val = ngx_palloc(cf->pool, sizeof(ngx_str_t)); if (ctx->val == NULL) { return NGX_CONF_ERROR; } *ctx->val = value[2]; ctx->key_len = 104; /* now an item is 640B at length. */ ctx->recycle_rate = 167; /* rate threshold is 10r/min */ shm_zone = ngx_shared_memory_add(cf, &value[1], size, &ngx_http_reqstat_module); if (shm_zone == NULL) { return NGX_CONF_ERROR; } if (shm_zone->data) { ctx = shm_zone->data; ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound to value \"%V\"", &cmd->name, &value[1], ctx->val); return NGX_CONF_ERROR; } shm_zone->init = ngx_http_reqstat_init_zone; shm_zone->data = ctx; return NGX_CONF_OK; }
static char * ngx_http_req_status_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ssize_t size; ngx_str_t *value; ngx_http_req_status_zone_t *ctx, **pctx; ngx_http_req_status_main_conf_t *rmcf; ngx_http_compile_complex_value_t ccv; value = cf->args->elts; size = ngx_parse_size(&value[3]); if (size == NGX_ERROR) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid size of %V \"%V\"", &cmd->name, &value[3]); return NGX_CONF_ERROR; } if (size < (ssize_t) (8 * ngx_pagesize)) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is too small", &cmd->name, &value[1]); return NGX_CONF_ERROR; } ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_req_status_zone_t)); if (ctx == NULL){ return NGX_CONF_ERROR; } ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); ccv.cf = cf; ccv.value = &value[2]; ccv.complex_value = &ctx->key; if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { return NGX_CONF_ERROR; } ctx->shm_zone = ngx_shared_memory_add(cf, &value[1], size, &ngx_http_req_status_module); if (ctx->shm_zone == NULL) { return NGX_CONF_ERROR; } if (ctx->shm_zone->data) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V \"%V\" is already bound", &cmd->name, &value[1]); return NGX_CONF_ERROR; } ctx->shm_zone->init = ngx_http_req_status_init_zone; ctx->shm_zone->data = ctx; rmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_req_status_module); pctx = ngx_array_push(&rmcf->zones); if (pctx == NULL){ return NGX_CONF_ERROR; } *pctx = ctx; return NGX_CONF_OK; }
static char * ngx_http_tfs_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { ngx_int_t add; ngx_str_t *value, s; ngx_url_t u; ngx_http_tfs_loc_conf_t *tlcf; ngx_http_tfs_main_conf_t *tmcf; ngx_http_core_loc_conf_t *clcf; value = cf->args->elts; clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); tmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_tfs_module); tlcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_tfs_module); if (ngx_strncasecmp(value[1].data, (u_char *) "tfs://", 6) == 0) { add = 6; } else { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid URL prefix in tfs_pass"); return NGX_CONF_ERROR; } ngx_memzero(&u, sizeof(ngx_url_t)); u.url.len = value[1].len - add; u.url.data = value[1].data + add; u.uri_part = 1; u.no_resolve = 1; tlcf->upstream = ngx_http_tfs_upstream_add(cf, &u, NGX_HTTP_TFS_UPSTREAM_FIND); if (tlcf->upstream == NULL) { return NGX_CONF_ERROR; } clcf->handler = ngx_http_tfs_handler; if (clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; } if (tlcf->upstream->enable_rcs) { if (tlcf->upstream->local_addr_text[0] == '\0') { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign net device name, " "use directives \"rcs_interface\" "); return NGX_CONF_ERROR; } tlcf->upstream->rcs_shm_zone = ngx_shared_memory_add(cf, &tlcf->upstream->rcs_zone_name, 0, &ngx_http_tfs_module); if (tlcf->upstream->rcs_shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign rcs shm zone," "use directives \"rcs_zone\" "); return NGX_CONF_ERROR; } } if (tmcf->local_block_cache_ctx != NULL) { s.data = (u_char *) NGX_HTTP_TFS_BLOCK_CACHE_ZONE_NAME; s.len = sizeof(NGX_HTTP_TFS_BLOCK_CACHE_ZONE_NAME) - 1; tmcf->block_cache_shm_zone = ngx_shared_memory_add(cf, &s, 0, &ngx_http_tfs_module); if (tmcf->block_cache_shm_zone == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "in tfs module must assign block cache shm zone," "use directives \"tfs_block_cache_zone\" "); return NGX_CONF_ERROR; } } tlcf->upstream->used = 1; return NGX_CONF_OK; }