static ngx_int_t
ngx_http_add_regex_server_name(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
    ngx_http_regex_t *regex)
{
    ngx_regex_elt_t  *re;

    if (rlcf->server_name_regex == NGX_CONF_UNSET_PTR) {
        rlcf->server_name_regex = ngx_array_create(cf->pool, 2,
                                                   sizeof(ngx_regex_elt_t));
        if (rlcf->server_name_regex == NULL) {
            return NGX_ERROR;
        }
    }

    re = ngx_array_push(rlcf->server_name_regex);
    if (re == NULL) {
        return NGX_ERROR;
    }

    re->regex = regex->regex;
    re->name = regex->name.data;

    return NGX_OK;
}
Example #2
0
/*
 * 设置配置中的 keyval slot
 */
char *
ngx_conf_set_keyval_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char  *p = conf;

    ngx_str_t         *value;
    ngx_array_t      **a;
    ngx_keyval_t      *kv;
    ngx_conf_post_t   *post;

    a = (ngx_array_t **) (p + cmd->offset);

    if (*a == NULL) {
        *a = ngx_array_create(cf->pool, 4, sizeof(ngx_keyval_t));
        if (*a == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    kv = ngx_array_push(*a);
    if (kv == NULL) {
        return NGX_CONF_ERROR;
    }

    value = cf->args->elts;

    kv->key = value[1];
    kv->value = value[2];

    if (cmd->post) {
        post = cmd->post;
        return post->post_handler(cf, post, kv);
    }

    return NGX_CONF_OK;
}
Example #3
0
static ngx_udp_endpoint_t *
ngx_http_statsd_add_endpoint(ngx_conf_t *cf, ngx_statsd_addr_t *peer_addr)
{
    ngx_http_statsd_main_conf_t    *umcf;
    ngx_udp_endpoint_t             *endpoint;

    umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_statsd_module);

    if(umcf->endpoints == NULL) {
        umcf->endpoints = ngx_array_create(cf->pool, 2, sizeof(ngx_udp_endpoint_t));
        if (umcf->endpoints == NULL) {
            return NULL;
        }
    }

    endpoint = ngx_array_push(umcf->endpoints);
    if (endpoint == NULL) {
        return NULL;
    }

    endpoint->peer_addr = *peer_addr;

    return endpoint;
}
static char* ngx_http_gridfs_merge_loc_conf(ngx_conf_t* cf, void* void_parent, void* void_child) {
    ngx_http_gridfs_loc_conf_t *parent = void_parent;
    ngx_http_gridfs_loc_conf_t *child = void_child;
    ngx_http_gridfs_main_conf_t *gridfs_main_conf = ngx_http_conf_get_module_main_conf(cf, ngx_http_gridfs_module);
    ngx_http_gridfs_loc_conf_t **gridfs_loc_conf;
    ngx_http_mongod_server_t *mongod_server;

    ngx_conf_merge_str_value(child->db, parent->db, NULL);
    ngx_conf_merge_str_value(child->root_collection, parent->root_collection, "fs");
    ngx_conf_merge_str_value(child->field, parent->field, "_id");
    ngx_conf_merge_uint_value(child->type, parent->type, BSON_OID);
    ngx_conf_merge_str_value(child->user, parent->user, NULL);
    ngx_conf_merge_str_value(child->pass, parent->pass, NULL);
    ngx_conf_merge_str_value(child->mongo, parent->mongo, "127.0.0.1:27017");

    if (child->mongods == NGX_CONF_UNSET_PTR) {
        if (parent->mongods != NGX_CONF_UNSET_PTR) {
            child->mongods = parent->mongods;
        } else {
            child->mongods = ngx_array_create(cf->pool, 4,
                                              sizeof(ngx_http_mongod_server_t));
            mongod_server = ngx_array_push(child->mongods);
            mongod_server->host.data = (u_char *)"127.0.0.1";
            mongod_server->host.len = sizeof("127.0.0.1") - 1;
            mongod_server->port = 27017;
        }
    }

    // Add the local gridfs conf to the main gridfs conf
    if (child->db.data) {
        gridfs_loc_conf = ngx_array_push(&gridfs_main_conf->loc_confs);
        *gridfs_loc_conf = child;
    }

    return NGX_CONF_OK;
}
static char *
ngx_http_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_index_loc_conf_t  *prev = parent;
    ngx_http_index_loc_conf_t  *conf = child;

    ngx_http_index_t  *index;

    if (conf->indices == NULL) {
        conf->indices = prev->indices;
        conf->max_index_len = prev->max_index_len;
    }

    if (conf->indices == NULL) {
        conf->indices = ngx_array_create(cf->pool, 1, sizeof(ngx_http_index_t));
        if (conf->indices == NULL) {
            return NGX_CONF_ERROR;
        }

        index = ngx_array_push(conf->indices);
        if (index == NULL) {
            return NGX_CONF_ERROR;
        }

        index->name.len = sizeof(NGX_HTTP_DEFAULT_INDEX);
        index->name.data = (u_char *) NGX_HTTP_DEFAULT_INDEX;
        index->lengths = NULL;
        index->values = NULL;

        conf->max_index_len = sizeof(NGX_HTTP_DEFAULT_INDEX);

        return NGX_CONF_OK;
    }

    return NGX_CONF_OK;
}
ngx_array_t * /* ngx_str_t */
ngx_http_google_explode(ngx_http_request_t * r,
                        ngx_str_t          * v, const char * de)
{
  ngx_str_t   * s;
  ngx_array_t * ss = ngx_array_create(r->pool, 4, sizeof(ngx_keyval_t));
  if (!ss) return NULL;
  
  char * dup = ngx_pcalloc(r->pool, v->len + 1);
  if (!dup) return NULL;
  memcpy(dup, v->data, v->len);
  
  char * pch, * brkt; size_t len;
  pch = strtok_r(dup, de, &brkt);
  for (; pch; pch = strtok_r(NULL, de, &brkt))
  {
    if (!(len = strlen(pch))) continue;
    s = ngx_array_push(ss);
    if (!s) return NULL;
   *s = ngx_http_google_trim(pch, strlen(pch));
  }
  
  return ss;
}
//#define readconf_debug
static char *
ngx_http_dummy_read_conf(ngx_conf_t *cf, ngx_command_t *cmd, 
			 void *conf)
{
  ngx_http_dummy_loc_conf_t	*alcf = conf, **bar;
  
  ngx_http_dummy_main_conf_t	*main_cf;
  ngx_str_t			*value;
  ngx_http_rule_t		rule, *rule_r;
  ngx_http_check_rule_t		*rule_c;
  ngx_http_custom_rule_location_t	*location;
  unsigned int	i;
  u_char			*var_end;
  
#ifdef readconf_debug
  if (cf) {
    value = cf->args->elts;
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "TOP READ CONF %V %V", 
		       &(value[0]), &(value[1]));  
  }
#endif
  if (!alcf || !cf)
    return (NGX_CONF_ERROR); 
  value = cf->args->elts;
  main_cf = ngx_http_conf_get_module_main_conf(cf, ngx_http_naxsi_module);
  if (!alcf->pushed) { 
    bar = ngx_array_push(main_cf->locations);
    if (!bar)
      return (NGX_CONF_ERROR);
    *bar = alcf;
    alcf->pushed = 1;
  }
  /* store denied URL for location */
  if (!ngx_strcmp(value[0].data, TOP_DENIED_URL_T) && value[1].len) {
    alcf->denied_url = ngx_pcalloc(cf->pool, sizeof(ngx_str_t));
    if (!alcf->denied_url)
      return (NGX_CONF_ERROR);
    alcf->denied_url->data = ngx_pcalloc(cf->pool, value[1].len+1);
    if (!alcf->denied_url->data)
      return (NGX_CONF_ERROR);
    memcpy(alcf->denied_url->data, value[1].data, value[1].len);
    alcf->denied_url->len = value[1].len;
    return (NGX_CONF_OK);
  }
  /* it's a flagrule, just a hack to enable/disable mod */
  if (!ngx_strcmp(value[0].data, TOP_ENABLED_FLAG_T)) {
    alcf->enabled = 1;
    return (NGX_CONF_OK);
  }
  /* it's a flagrule, just a hack to enable/disable mod */
  if (!ngx_strcmp(value[0].data, TOP_DISABLED_FLAG_T)) {
    alcf->force_disabled = 1;
    return (NGX_CONF_OK);
  }
  /* it's a flagrule, currently just a hack to enable/disable learning mode */
  if (!ngx_strcmp(value[0].data, TOP_LEARNING_FLAG_T)) {
    alcf->learning = 1;
    return (NGX_CONF_OK);
  }
  if (!ngx_strcmp(value[0].data, TOP_BASIC_RULE_T)) {
#ifdef readconf_debug
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "XX-TOP READ CONF %s", 
		       value[0].data);  
#endif
    memset(&rule, 0, sizeof(ngx_http_rule_t));
    if (ngx_http_dummy_cfg_parse_one_rule(cf, value, &rule, 
					   cf->args->nelts) != NGX_CONF_OK)
      {
	ngx_http_dummy_line_conf_error(cf, value);
	return (NGX_CONF_ERROR);
      }
    /* push in whitelist rules, as it have a whitelist ID array */
    if (rule.wl_id) {
#ifdef readconf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "pushing rule %d in whitelist rules", 
			 rule.rule_id);  
#endif
      if (alcf->whitelist_rules == NULL) {
	alcf->whitelist_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	if (alcf->whitelist_rules == NULL) {
	  return NGX_CONF_ERROR;
	}
      }
      rule_r = ngx_array_push(alcf->whitelist_rules);
      if (!rule_r) {
	return (NGX_CONF_ERROR);
      }
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* else push in appropriate ruleset */
    else {
      if (rule.br->headers) {
#ifdef readconf_debug
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			   "pushing rule %d in header rules", 
			   rule.rule_id);  
#endif
	if (alcf->header_rules == NULL)  {
	  alcf->header_rules = ngx_array_create(cf->pool, 2,
						sizeof(ngx_http_rule_t));
	  if (alcf->header_rules == NULL) 
	    return NGX_CONF_ERROR;
	}
	rule_r = ngx_array_push(alcf->header_rules);
	if (!rule_r) return (NGX_CONF_ERROR);
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in body match rules (POST/PUT) */
      if (rule.br->body || rule.br->body_var) {
#ifdef readconf_debug
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			   "pushing rule %d in body rules", rule.rule_id);  
#endif
	if (alcf->body_rules == NULL) {
	  alcf->body_rules = ngx_array_create(cf->pool, 2,
					      sizeof(ngx_http_rule_t));
	  if (alcf->body_rules == NULL) 
	    return NGX_CONF_ERROR;
	}
	rule_r = ngx_array_push(alcf->body_rules);
	if (!rule_r) return (NGX_CONF_ERROR);
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in generic rules, as it's matching the URI */
      if (rule.br->url) {
#ifdef readconf_debug
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			   "pushing rule %d in generic rules", 
			   rule.rule_id);  
#endif
	if (alcf->generic_rules == NULL) {
	  alcf->generic_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	  if (alcf->generic_rules == NULL) 
	    return NGX_CONF_ERROR;
	}
	rule_r = ngx_array_push(alcf->generic_rules);
	if (!rule_r) return (NGX_CONF_ERROR);
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in GET arg rules, but we should push in POST rules too  */
      if (rule.br->args_var || rule.br->args) {
#ifdef readconf_debug
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			   "pushing rule %d in GET rules", rule.rule_id);  
#endif
	if (alcf->get_rules == NULL) {
	  alcf->get_rules = ngx_array_create(cf->pool, 2,
					     sizeof(ngx_http_rule_t));
	  if (alcf->get_rules == NULL) 
	    return NGX_CONF_ERROR;
	}
	rule_r = ngx_array_push(alcf->get_rules);
	if (!rule_r) return (NGX_CONF_ERROR);
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in custom locations. It's a rule matching a VAR_NAME or an EXACT_URI :
	 - GET_VAR, POST_VAR, URI */
      if (rule.br->custom_location) {
#ifdef readconf_debug
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			   "pushing rule %d in custom_location rules", 
			   rule.rule_id);  
#endif
	location = rule.br->custom_locations->elts;
	for (i = 0; i < rule.br->custom_locations->nelts; i++) {
	  if (location[i].args_var) {
	    if (alcf->get_rules == NULL) {
	      alcf->get_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	      if (alcf->get_rules == NULL) 
		return NGX_CONF_ERROR;
	    }
	    rule_r = ngx_array_push(alcf->get_rules);
	    if (!rule_r) return (NGX_CONF_ERROR);
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	  }
	  if (location[i].body_var) {
	    if (alcf->body_rules == NULL) {
	      alcf->body_rules = ngx_array_create(cf->pool, 2,
						  sizeof(ngx_http_rule_t));
	      if (alcf->body_rules == NULL) 
		return NGX_CONF_ERROR;
	    }
	    rule_r = ngx_array_push(alcf->body_rules);
	    if (!rule_r) return (NGX_CONF_ERROR);
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
		      
	  }
	  if (location[i].headers_var) {
	    if (alcf->header_rules == NULL) {
	      alcf->header_rules = ngx_array_create(cf->pool, 2,
						    sizeof(ngx_http_rule_t));
	      if (alcf->header_rules == NULL) 
		return NGX_CONF_ERROR;
	    }
	    rule_r = ngx_array_push(alcf->header_rules);
	    if (!rule_r) return (NGX_CONF_ERROR);
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	  }
	}
      }
    }
    return (NGX_CONF_OK);
  }
  /* this should be moved in a function, plus this code is not safe. */
  else if (!ngx_strcmp(value[0].data, TOP_CHECK_RULE_T)) {
#ifdef readconf_debug
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
		       "pushing rule %d in check rules", rule.rule_id);  
#endif
    i = 0;
    if (!alcf->check_rules)
      alcf->check_rules = ngx_array_create(cf->pool, 2, 
					   sizeof(ngx_http_check_rule_t));
    if (!alcf->check_rules)
      return (NGX_CONF_ERROR);
    rule_c = ngx_array_push(alcf->check_rules);
    if (!rule_c) return (NGX_CONF_ERROR);
    memset(rule_c, 0, sizeof(ngx_http_check_rule_t));
    /* process the first word : score rule */
    if (value[1].data[i] == '$') {
#ifdef MDBG
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "XX-special score rule !");
#endif
	var_end = (u_char *) ngx_strchr((value[1].data)+i, ' ');
	if (!var_end) {
	  ngx_http_dummy_line_conf_error(cf, value);
	  return (NGX_CONF_ERROR);
	}
	rule_c->sc_tag.data = ngx_pcalloc(cf->pool, var_end - value[1].data +1);
	if (!rule_c->sc_tag.data)
	  return (NGX_CONF_ERROR);
	memcpy(rule_c->sc_tag.data, value[1].data, (var_end - value[1].data));
	i += (var_end - value[1].data) + 1;
	rule_c->sc_tag.len = (var_end - value[1].data);
      }
    else {
      ngx_http_dummy_line_conf_error(cf, value);
      return (NGX_CONF_ERROR);
    }
    // move to next word
    while (value[1].data[i] && value[1].data[i] == ' ')
      i++;
    // get the comparison type
    if (value[1].data[i] == '>' && value[1].data[i+1] == '=')
      rule_c->cmp = SUP_OR_EQUAL;
    else if (value[1].data[i] == '>' && value[1].data[i+1] != '=')
      rule_c->cmp = SUP;
    else if (value[1].data[i] == '<' && value[1].data[i+1] == '=')
      rule_c->cmp = INF_OR_EQUAL;
    else if (value[1].data[i] == '<' && value[1].data[i+1] != '=')
      rule_c->cmp = INF;
    else {
      ngx_http_dummy_line_conf_error(cf, value);
      return (NGX_CONF_ERROR);
    }
    // move to next word
    while (value[1].data[i] && !(value[1].data[i] >= '0' && 
				 value[1].data[i] <= '9') && (value[1].data[i] != '-'))
      i++;
#ifdef readconf_debug
    ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
		       "XX-special score in checkrule:%s from (%d)", 
		       value[1].data, atoi((const char *)value[1].data+i));
#endif
    // get the score
    rule_c->sc_score = atoi((const char *)(value[1].data+i));
    /* process the second word : Action rule */
    if (!ngx_strstr(value[2].data, "BLOCK"))
      rule_c->block = 1;
    else if (!ngx_strstr(value[2].data, "ALLOW"))
      rule_c->block = 1;
    else if (!ngx_strstr(value[2].data, "LOG"))
      rule_c->block = 1;
    else {
      ngx_http_dummy_line_conf_error(cf, value);
      return (NGX_CONF_ERROR);
    }
    return (NGX_CONF_OK);
  }
  ngx_http_dummy_line_conf_error(cf, value);
  return (NGX_CONF_ERROR);
}
char *
ngx_postgres_conf_query(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t                         *value = cf->args->elts;
    ngx_str_t                          sql = value[cf->args->nelts - 1];
    ngx_postgres_loc_conf_t           *pglcf = conf;
    ngx_http_compile_complex_value_t   ccv;
    ngx_postgres_mixed_t              *query;
    ngx_conf_bitmask_t                *b;
    ngx_uint_t                         methods, i, j;

    dd("entering");

    if (sql.len == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: empty query in \"%V\" directive",
                           &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    if (cf->args->nelts == 2) {
        /* default query */
        dd("default query");

        if (pglcf->query.def != NULL) {
            dd("returning");
            return "is duplicate";
        }

        pglcf->query.def = ngx_palloc(cf->pool, sizeof(ngx_postgres_mixed_t));
        if (pglcf->query.def == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        methods = 0xFFFF;
        query = pglcf->query.def;
    } else {
        /* method-specific query */
        dd("method-specific query");

        methods = 0;

        for (i = 1; i < cf->args->nelts - 1; i++) {
            b = ngx_postgres_http_methods;
            for (j = 0; b[j].name.len; j++) {
                if ((b[j].name.len == value[i].len)
                    && (ngx_strcasecmp(b[j].name.data, value[i].data) == 0))
                {
                    if (pglcf->query.methods_set & b[j].mask) {
                        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                           "postgres: method \"%V\" is"
                                           " duplicate in \"%V\" directive",
                                           &value[i], &cmd->name);

                        dd("returning NGX_CONF_ERROR");
                        return NGX_CONF_ERROR;
                    }

                    methods |= b[j].mask;
                    break;
                }
            }

            if (b[j].name.len == 0) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "postgres: invalid method \"%V\""
                                   " in \"%V\" directive",
                                   &value[i], &cmd->name);

                dd("returning NGX_CONF_ERROR");
                return NGX_CONF_ERROR;
            }
        }

        if (pglcf->query.methods == NULL) {
            pglcf->query.methods = ngx_array_create(cf->pool, 4,
                                       sizeof(ngx_postgres_mixed_t));
            if (pglcf->query.methods == NULL) {
                dd("returning NGX_CONF_ERROR");
                return NGX_CONF_ERROR;
            }
        }

        query = ngx_array_push(pglcf->query.methods);
        if (query == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        pglcf->query.methods_set |= methods;
    }

    if (ngx_http_script_variables_count(&sql)) {
        /* complex value */
        dd("complex value");

        query->key = methods;

        query->cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
        if (query->cv == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

        ccv.cf = cf;
        ccv.value = &sql;
        ccv.complex_value = query->cv;

        if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }
    } else {
        /* simple value */
        dd("simple value");

        query->key = methods;
        query->sv = sql;
        query->cv = NULL;
    }

    dd("returning NGX_CONF_OK");
    return NGX_CONF_OK;
}
char *
ngx_postgres_conf_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t                *value = cf->args->elts;
    ngx_postgres_loc_conf_t  *pglcf = conf;
    ngx_postgres_variable_t  *pgvar;
    ngx_conf_enum_t          *e;
    ngx_int_t                 idx;
    ngx_uint_t                i;

    dd("entering");

    if (value[1].len < 2) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: empty variable name in \"%V\" directive",
                           &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    if (value[1].data[0] != '$') {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: invalid variable name \"%V\""
                           " in \"%V\" directive", &value[1], &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

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

    if (value[3].len == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: empty column in \"%V\" directive",
                           &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    if (pglcf->variables == NGX_CONF_UNSET_PTR) {
        pglcf->variables = ngx_array_create(cf->pool, 4,
                                            sizeof(ngx_postgres_variable_t));
        if (pglcf->variables == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }
    }

    pgvar = ngx_array_push(pglcf->variables);
    if (pgvar == NULL) {
        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    pgvar->idx = pglcf->variables->nelts - 1;

    pgvar->var = ngx_http_add_variable(cf, &value[1], 0);
    if (pgvar->var == NULL) {
        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    idx = ngx_http_get_variable_index(cf, &value[1]);
    if (idx == NGX_ERROR) {
        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    /*
     * Check if "$variable" was previously defined,
     * back-off even if it was marked as "CHANGEABLE".
     */
    if (pgvar->var->get_handler != NULL) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: variable \"$%V\" is duplicate"
                           " in \"%V\" directive", &value[1], &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    pgvar->var->get_handler = ngx_postgres_variable_get_custom;
    pgvar->var->data = (uintptr_t) pgvar;

    pgvar->value.row = ngx_atoi(value[2].data, value[2].len);
    if (pgvar->value.row == NGX_ERROR) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: invalid row number \"%V\""
                           " in \"%V\" directive", &value[2], &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    pgvar->value.column = ngx_atoi(value[3].data, value[3].len);
    if (pgvar->value.column == NGX_ERROR) {
        /* get column by name */
        pgvar->value.col_name = ngx_pnalloc(cf->pool, value[3].len + 1);
        if (pgvar->value.col_name == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        (void) ngx_cpystrn(pgvar->value.col_name,
                           value[3].data, value[3].len + 1);
    }

    if (cf->args->nelts == 4) {
        /* default value */
        pgvar->value.required = 0;
    } else {
        /* user-specified value */
        e = ngx_postgres_requirement_options;
        for (i = 0; e[i].name.len; i++) {
            if ((e[i].name.len == value[4].len)
                && (ngx_strcasecmp(e[i].name.data, value[4].data) == 0))
            {
                pgvar->value.required = e[i].value;
                break;
            }
        }

        if (e[i].name.len == 0) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "postgres: invalid requirement option \"%V\""
                               " in \"%V\" directive", &value[4], &cmd->name);

            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }
    }

    dd("returning NGX_CONF_OK");
    return NGX_CONF_OK;
}
Example #10
0
char *
ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf)
{
    char  *p = conf;

    time_t                    valid;
    ngx_str_t                *value;
    ngx_uint_t                i, n, status;
    ngx_array_t             **a;
    ngx_http_cache_valid_t   *v;
    static ngx_uint_t         statuses[] = { 200, 301, 302 };

    a = (ngx_array_t **) (p + cmd->offset);

    if (*a == NGX_CONF_UNSET_PTR) {
        *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_cache_valid_t));
        if (*a == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    value = cf->args->elts;
    n = cf->args->nelts - 1;

    valid = ngx_parse_time(&value[n], 1);
    if (valid < 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid time value \"%V\"", &value[n]);
        return NGX_CONF_ERROR;
    }

    if (n == 1) {

        for (i = 0; i < 3; i++) {
            v = ngx_array_push(*a);
            if (v == NULL) {
                return NGX_CONF_ERROR;
            }

            v->status = statuses[i];
            v->valid = valid;
        }

        return NGX_CONF_OK;
    }

    for (i = 1; i < n; i++) {

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

            status = 0;

        } else {

            status = ngx_atoi(value[i].data, value[i].len);
            if (status < 100) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "invalid status \"%V\"", &value[i]);
                return NGX_CONF_ERROR;
            }
        }

        v = ngx_array_push(*a);
        if (v == NULL) {
            return NGX_CONF_ERROR;
        }

        v->status = status;
        v->valid = valid;
    }

    return NGX_CONF_OK;
}
Example #11
0
ngx_cycle_t *
ngx_init_cycle(ngx_cycle_t *old_cycle)
{
    void                *rv;
    char               **senv, **env;
    ngx_uint_t           i, n;
    ngx_log_t           *log;
    ngx_time_t          *tp;
    ngx_conf_t           conf;
    ngx_pool_t          *pool;
    ngx_cycle_t         *cycle, **old;
    ngx_shm_zone_t      *shm_zone, *oshm_zone;
    ngx_list_part_t     *part, *opart;
    ngx_open_file_t     *file;
    ngx_listening_t     *ls, *nls;
    ngx_core_conf_t     *ccf, *old_ccf;
    ngx_core_module_t   *module;
    char                 hostname[NGX_MAXHOSTNAMELEN];

    ngx_timezone_update();

    /* force localtime update with a new timezone */

    tp = ngx_timeofday();
    tp->sec = 0;

    ngx_time_update();


    log = old_cycle->log;

    pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
    if (pool == NULL) {
        return NULL;
    }
    pool->log = log;

    cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t));
    if (cycle == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    cycle->pool = pool;
    cycle->log = log;
    cycle->old_cycle = old_cycle;

    cycle->conf_prefix.len = old_cycle->conf_prefix.len;
    cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix);
    if (cycle->conf_prefix.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    cycle->prefix.len = old_cycle->prefix.len;
    cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix);
    if (cycle->prefix.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    cycle->conf_file.len = old_cycle->conf_file.len;
    cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1);
    if (cycle->conf_file.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }
    ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data,
                old_cycle->conf_file.len + 1);

    cycle->conf_param.len = old_cycle->conf_param.len;
    cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param);
    if (cycle->conf_param.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }


    n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;

    cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
    if (cycle->paths.elts == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    cycle->paths.nelts = 0;
    cycle->paths.size = sizeof(ngx_path_t *);
    cycle->paths.nalloc = n;
    cycle->paths.pool = pool;


    if (old_cycle->open_files.part.nelts) {
        n = old_cycle->open_files.part.nelts;
        for (part = old_cycle->open_files.part.next; part; part = part->next) {
            n += part->nelts;
        }

    } else {
        n = 20;
    }

    if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }


    if (old_cycle->shared_memory.part.nelts) {
        n = old_cycle->shared_memory.part.nelts;
        for (part = old_cycle->shared_memory.part.next; part; part = part->next)
        {
            n += part->nelts;
        }

    } else {
        n = 1;
    }

    if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t))
        != NGX_OK)
    {
        ngx_destroy_pool(pool);
        return NULL;
    }

    n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;

    cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
    if (cycle->listening.elts == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    cycle->listening.nelts = 0;
    cycle->listening.size = sizeof(ngx_listening_t);
    cycle->listening.nalloc = n;
    cycle->listening.pool = pool;


    ngx_queue_init(&cycle->reusable_connections_queue);


    cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *));
    if (cycle->conf_ctx == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }


    if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) {
        ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed");
        ngx_destroy_pool(pool);
        return NULL;
    }

    /* on Linux gethostname() silently truncates name that does not fit */

    hostname[NGX_MAXHOSTNAMELEN - 1] = '\0';
    cycle->hostname.len = ngx_strlen(hostname);

    cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len);
    if (cycle->hostname.data == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);


    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = ngx_modules[i]->ctx;

        if (module->create_conf) {
            rv = module->create_conf(cycle);
            if (rv == NULL) {
                ngx_destroy_pool(pool);
                return NULL;
            }
            cycle->conf_ctx[ngx_modules[i]->index] = rv;
        }
    }


    senv = environ;


    ngx_memzero(&conf, sizeof(ngx_conf_t));
    /* STUB: init array ? */
    conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
    if (conf.args == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }

    conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
    if (conf.temp_pool == NULL) {
        ngx_destroy_pool(pool);
        return NULL;
    }


    conf.ctx = cycle->conf_ctx;
    conf.cycle = cycle;
    conf.pool = pool;
    conf.log = log;
    conf.module_type = NGX_CORE_MODULE;
    conf.cmd_type = NGX_MAIN_CONF;

#if 0
    log->log_level = NGX_LOG_DEBUG_ALL;
#endif

    if (ngx_conf_param(&conf) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }

    if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
        environ = senv;
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }

    if (ngx_test_config && !ngx_quiet_mode) {
        ngx_log_stderr(0, "the configuration file %s syntax is ok",
                       cycle->conf_file.data);
    }

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->type != NGX_CORE_MODULE) {
            continue;
        }

        module = ngx_modules[i]->ctx;

        if (module->init_conf) {
            if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
                == NGX_CONF_ERROR)
            {
                environ = senv;
                ngx_destroy_cycle_pools(&conf);
                return NULL;
            }
        }
    }

    if (ngx_process == NGX_PROCESS_SIGNALLER) {
        return cycle;
    }

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ngx_test_config) {

        if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
            goto failed;
        }

    } else if (!ngx_is_init_cycle(old_cycle)) {

        /*
         * we do not create the pid file in the first ngx_init_cycle() call
         * because we need to write the demonized process pid
         */

        old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
                                                   ngx_core_module);
        if (ccf->pid.len != old_ccf->pid.len
            || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0)
        {
            /* new pid file name */

            if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) {
                goto failed;
            }

            ngx_delete_pidfile(old_cycle);
        }
    }


    if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) {
        goto failed;
    }


    if (ngx_create_paths(cycle, ccf->user) != NGX_OK) {
        goto failed;
    }


    if (ngx_log_open_default(cycle) != NGX_OK) {
        goto failed;
    }

    /* open the new files */

    part = &cycle->open_files.part;
    file = part->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }
            part = part->next;
            file = part->elts;
            i = 0;
        }

        if (file[i].name.len == 0) {
            continue;
        }

        file[i].fd = ngx_open_file(file[i].name.data,
                                   NGX_FILE_APPEND,
                                   NGX_FILE_CREATE_OR_OPEN,
                                   NGX_FILE_DEFAULT_ACCESS);

        ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0,
                       "log: %p %d \"%s\"",
                       &file[i], file[i].fd, file[i].name.data);

        if (file[i].fd == NGX_INVALID_FILE) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          ngx_open_file_n " \"%s\" failed",
                          file[i].name.data);
            goto failed;
        }

#if !(NGX_WIN32)
        if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          "fcntl(FD_CLOEXEC) \"%s\" failed",
                          file[i].name.data);
            goto failed;
        }
#endif
    }

    cycle->log = &cycle->new_log;
    pool->log = &cycle->new_log;


    /* create shared memory */

    part = &cycle->shared_memory.part;
    shm_zone = part->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }
            part = part->next;
            shm_zone = part->elts;
            i = 0;
        }

        if (shm_zone[i].shm.size == 0) {
            ngx_log_error(NGX_LOG_EMERG, log, 0,
                          "zero size shared memory zone \"%V\"",
                          &shm_zone[i].shm.name);
            goto failed;
        }

        shm_zone[i].shm.log = cycle->log;

        opart = &old_cycle->shared_memory.part;
        oshm_zone = opart->elts;

        for (n = 0; /* void */ ; n++) {

            if (n >= opart->nelts) {
                if (opart->next == NULL) {
                    break;
                }
                opart = opart->next;
                oshm_zone = opart->elts;
                n = 0;
            }

            if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) {
                continue;
            }

            if (ngx_strncmp(shm_zone[i].shm.name.data,
                            oshm_zone[n].shm.name.data,
                            shm_zone[i].shm.name.len)
                != 0)
            {
                continue;
            }

            if (shm_zone[i].tag == oshm_zone[n].tag
                && shm_zone[i].shm.size == oshm_zone[n].shm.size)
            {
                shm_zone[i].shm.addr = oshm_zone[n].shm.addr;

                if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data)
                    != NGX_OK)
                {
                    goto failed;
                }

                goto shm_zone_found;
            }

            ngx_shm_free(&oshm_zone[n].shm);

            break;
        }

        if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) {
            goto failed;
        }

        if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) {
            goto failed;
        }

        if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) {
            goto failed;
        }

    shm_zone_found:

        continue;
    }


    /* handle the listening sockets */

    if (old_cycle->listening.nelts) {
        ls = old_cycle->listening.elts;
        for (i = 0; i < old_cycle->listening.nelts; i++) {
            ls[i].remain = 0;
        }

        nls = cycle->listening.elts;
        for (n = 0; n < cycle->listening.nelts; n++) {

            for (i = 0; i < old_cycle->listening.nelts; i++) {
                if (ls[i].ignore) {
                    continue;
                }

                if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK)
                {
                    nls[n].fd = ls[i].fd;
                    nls[n].previous = &ls[i];
                    ls[i].remain = 1;

                    if (ls[n].backlog != nls[i].backlog) {
                        nls[n].listen = 1;
                    }

#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)

                    /*
                     * FreeBSD, except the most recent versions,
                     * could not remove accept filter
                     */
                    nls[n].deferred_accept = ls[i].deferred_accept;

                    if (ls[i].accept_filter && nls[n].accept_filter) {
                        if (ngx_strcmp(ls[i].accept_filter,
                                       nls[n].accept_filter)
                            != 0)
                        {
                            nls[n].delete_deferred = 1;
                            nls[n].add_deferred = 1;
                        }

                    } else if (ls[i].accept_filter) {
                        nls[n].delete_deferred = 1;

                    } else if (nls[n].accept_filter) {
                        nls[n].add_deferred = 1;
                    }
#endif

#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)

                    if (ls[n].deferred_accept && !nls[n].deferred_accept) {
                        nls[n].delete_deferred = 1;

                    } else if (ls[i].deferred_accept != nls[n].deferred_accept)
                    {
                        nls[n].add_deferred = 1;
                    }
#endif
                    break;
                }
            }

            if (nls[n].fd == (ngx_socket_t) -1) {
                nls[n].open = 1;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
                if (nls[n].accept_filter) {
                    nls[n].add_deferred = 1;
                }
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
                if (nls[n].deferred_accept) {
                    nls[n].add_deferred = 1;
                }
#endif
            }
        }

    } else {
        ls = cycle->listening.elts;
        for (i = 0; i < cycle->listening.nelts; i++) {
            ls[i].open = 1;
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
            if (ls[i].accept_filter) {
                ls[i].add_deferred = 1;
            }
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
            if (ls[i].deferred_accept) {
                ls[i].add_deferred = 1;
            }
#endif
        }
    }

    if (ngx_open_listening_sockets(cycle) != NGX_OK) {
        goto failed;
    }

    if (!ngx_test_config) {
        ngx_configure_listening_sockets(cycle);
    }


    /* commit the new cycle configuration */

    if (!ngx_use_stderr) {
        (void) ngx_log_redirect_stderr(cycle);
    }

    pool->log = cycle->log;

    for (i = 0; ngx_modules[i]; i++) {
        if (ngx_modules[i]->init_module) {
            if (ngx_modules[i]->init_module(cycle) != NGX_OK) {
                /* fatal */
                exit(1);
            }
        }
    }


    /* close and delete stuff that lefts from an old cycle */

    /* free the unnecessary shared memory */

    opart = &old_cycle->shared_memory.part;
    oshm_zone = opart->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= opart->nelts) {
            if (opart->next == NULL) {
                goto old_shm_zone_done;
            }
            opart = opart->next;
            oshm_zone = opart->elts;
            i = 0;
        }

        part = &cycle->shared_memory.part;
        shm_zone = part->elts;

        for (n = 0; /* void */ ; n++) {

            if (n >= part->nelts) {
                if (part->next == NULL) {
                    break;
                }
                part = part->next;
                shm_zone = part->elts;
                n = 0;
            }

            if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len
                && ngx_strncmp(oshm_zone[i].shm.name.data,
                               shm_zone[n].shm.name.data,
                               oshm_zone[i].shm.name.len)
                == 0)
            {
                goto live_shm_zone;
            }
        }

        ngx_shm_free(&oshm_zone[i].shm);

    live_shm_zone:

        continue;
    }

old_shm_zone_done:


    /* close the unnecessary listening sockets */

    ls = old_cycle->listening.elts;
    for (i = 0; i < old_cycle->listening.nelts; i++) {

        if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
            continue;
        }

        if (ngx_close_socket(ls[i].fd) == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                          ngx_close_socket_n " listening socket on %V failed",
                          &ls[i].addr_text);
        }

#if (NGX_HAVE_UNIX_DOMAIN)

        if (ls[i].sockaddr->sa_family == AF_UNIX) {
            u_char  *name;

            name = ls[i].addr_text.data + sizeof("unix:") - 1;

            ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
                          "deleting socket %s", name);

            if (ngx_delete_file(name) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                              ngx_delete_file_n " %s failed", name);
            }
        }

#endif
    }


    /* close the unnecessary open files */

    part = &old_cycle->open_files.part;
    file = part->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }
            part = part->next;
            file = part->elts;
            i = 0;
        }

        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
            continue;
        }

        if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed",
                          file[i].name.data);
        }
    }

    ngx_destroy_pool(conf.temp_pool);

    if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {

        /*
         * perl_destruct() frees environ, if it is not the same as it was at
         * perl_construct() time, therefore we save the previous cycle
         * environment before ngx_conf_parse() where it will be changed.
         */

        env = environ;
        environ = senv;

        ngx_destroy_pool(old_cycle->pool);
        cycle->old_cycle = NULL;

        environ = env;

        return cycle;
    }


    if (ngx_temp_pool == NULL) {
        ngx_temp_pool = ngx_create_pool(128, cycle->log);
        if (ngx_temp_pool == NULL) {
            ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,
                          "could not create ngx_temp_pool");
            exit(1);
        }

        n = 10;
        ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
                                          n * sizeof(ngx_cycle_t *));
        if (ngx_old_cycles.elts == NULL) {
            exit(1);
        }
        ngx_old_cycles.nelts = 0;
        ngx_old_cycles.size = sizeof(ngx_cycle_t *);
        ngx_old_cycles.nalloc = n;
        ngx_old_cycles.pool = ngx_temp_pool;

        ngx_cleaner_event.handler = ngx_clean_old_cycles;
        ngx_cleaner_event.log = cycle->log;
        ngx_cleaner_event.data = &dumb;
        dumb.fd = (ngx_socket_t) -1;
    }

    ngx_temp_pool->log = cycle->log;

    old = ngx_array_push(&ngx_old_cycles);
    if (old == NULL) {
        exit(1);
    }
    *old = old_cycle;

    if (!ngx_cleaner_event.timer_set) {
        ngx_add_timer(&ngx_cleaner_event, 30000);
        ngx_cleaner_event.timer_set = 1;
    }

    return cycle;


failed:

    if (!ngx_is_init_cycle(old_cycle)) {
        old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx,
                                                   ngx_core_module);
        if (old_ccf->environment) {
            environ = old_ccf->environment;
        }
    }

    /* rollback the new cycle configuration */

    part = &cycle->open_files.part;
    file = part->elts;

    for (i = 0; /* void */ ; i++) {

        if (i >= part->nelts) {
            if (part->next == NULL) {
                break;
            }
            part = part->next;
            file = part->elts;
            i = 0;
        }

        if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) {
            continue;
        }

        if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
                          ngx_close_file_n " \"%s\" failed",
                          file[i].name.data);
        }
    }

    if (ngx_test_config) {
        ngx_destroy_cycle_pools(&conf);
        return NULL;
    }

    ls = cycle->listening.elts;
    for (i = 0; i < cycle->listening.nelts; i++) {
        if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
            continue;
        }

        if (ngx_close_socket(ls[i].fd) == -1) {
            ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                          ngx_close_socket_n " %V failed",
                          &ls[i].addr_text);
        }
    }

    ngx_destroy_cycle_pools(&conf);

    return NULL;
}
ngx_int_t
ngx_http_echo_exec_echo_foreach_split(ngx_http_request_t *r,
        ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
{
    ngx_http_echo_loc_conf_t    *elcf;
    ngx_str_t                   *delimiter, *compound;
    u_char                      *pos, *last, *end;
    ngx_str_t                   *choice;
    ngx_str_t                   *computed_arg_elts;
    ngx_array_t                 *cmds;
    ngx_http_echo_cmd_t         *cmd;
    ngx_http_echo_cmd_t         *cmd_elts;

    if (ctx->foreach != NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "Nested echo_foreach not supported yet.");
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    if (computed_args->nelts < 2) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "echo_foreach should take at least two arguments. "
                "(if your delimiter starts with \"-\", preceding it with a "
                "\"--\".)");

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    computed_arg_elts = computed_args->elts;

    compound  = &computed_arg_elts[1];

    dd("HEY coumpound len: %u", compound->len);

    ctx->foreach = ngx_palloc(r->pool, sizeof(ngx_http_echo_foreach_ctx_t));

    if (ctx->foreach == NULL) {
        return NGX_ERROR;
    }

    ctx->foreach->cmd_index = ctx->next_handler_cmd;

    ctx->foreach->next_choice = 0;

    ctx->foreach->choices = ngx_array_create(r->pool, 10, sizeof(ngx_str_t));
    if (ctx->foreach->choices == NULL) {
        return NGX_ERROR;
    }

    delimiter = &computed_arg_elts[0];

    pos = compound->data;
    end = compound->data + compound->len;

    while ((last = ngx_http_echo_strlstrn(pos, end, delimiter->data,
                   delimiter->len - 1)) != NULL)
    {
        dd("entered the loop");

        if (last == pos) {
            dd("!!! len == 0");
            pos = last + delimiter->len;
            continue;
        }

        choice = ngx_array_push(ctx->foreach->choices);
        if (choice == NULL) {
            return NGX_ERROR;
        }

        choice->data = pos;
        choice->len  = last - pos;
        pos = last + delimiter->len;
    }

    if (pos < end) {
        choice = ngx_array_push(ctx->foreach->choices);
        if (choice == NULL) {
            return NGX_ERROR;
        }

        choice->data = pos;
        choice->len  = end - pos;
    }

    if (ctx->foreach->choices->nelts == 0) {
        /* skip the foreach body entirely */
        elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
        cmds = elcf->handler_cmds;
        cmd_elts = cmds->elts;
        for (; ctx->next_handler_cmd < cmds->nelts;
                ctx->next_handler_cmd++) {
            cmd = &cmd_elts[ctx->next_handler_cmd + 1];
            if (cmd->opcode == echo_opcode_echo_end) {
                return NGX_OK;
            }
        }

    }

    return NGX_OK;
}
Example #13
0
/*
** This function sets up handlers for ACCESS_PHASE,
** and will call the hashtable creation function
** (whitelist aggregation)
*/
static ngx_int_t 
ngx_http_dummy_init(ngx_conf_t *cf)
{
  ngx_http_handler_pt *h;
  ngx_http_core_main_conf_t *cmcf;
  ngx_http_dummy_main_conf_t *main_cf;
  ngx_http_dummy_loc_conf_t **loc_cf;
  unsigned int 				i;
  
  cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
  main_cf = ngx_http_conf_get_module_main_conf(cf, ngx_http_naxsi_module);
  if (cmcf == NULL || 
      main_cf == NULL)
    return (NGX_ERROR); /*LCOV_EXCL_LINE*/
  
  /* Register for access phase */
  h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
  if (h == NULL) 
    return (NGX_ERROR); /*LCOV_EXCL_LINE*/
  
  *h = ngx_http_dummy_access_handler;
  /* Go with each locations registred in the srv_conf. */
  loc_cf = main_cf->locations->elts;
  
  for (i = 0; i < main_cf->locations->nelts; i++) {
    if (loc_cf[i]->enabled && (!loc_cf[i]->denied_url || loc_cf[i]->denied_url->len <= 0)) {
      /* LCOV_EXCL_START */
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "Missing DeniedURL, abort.");
      return (NGX_ERROR);
      /* LCOV_EXCL_STOP */
    }
    loc_cf[i]->flag_enable_h = ngx_hash_key_lc((u_char *)RT_ENABLE, strlen(RT_ENABLE));
    loc_cf[i]->flag_learning_h = ngx_hash_key_lc((u_char *)RT_LEARNING, strlen(RT_LEARNING));
    loc_cf[i]->flag_post_action_h = ngx_hash_key_lc((u_char *)RT_POST_ACTION, strlen(RT_POST_ACTION));
    loc_cf[i]->flag_extensive_log_h = ngx_hash_key_lc((u_char *)RT_EXTENSIVE_LOG, strlen(RT_EXTENSIVE_LOG));
    loc_cf[i]->flag_libinjection_xss_h = ngx_hash_key_lc((u_char *)RT_LIBINJECTION_XSS, strlen(RT_LIBINJECTION_XSS));
    loc_cf[i]->flag_libinjection_sql_h = ngx_hash_key_lc((u_char *)RT_LIBINJECTION_SQL, strlen(RT_LIBINJECTION_SQL));
    
    if(ngx_http_dummy_create_hashtables_n(loc_cf[i], cf) != NGX_OK) {
      /* LCOV_EXCL_START */
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "WhiteList Hash building failed");
      return (NGX_ERROR);
      /* LCOV_EXCL_STOP */
    }
  }
  
  /* initialize prng (used for fragmented logs) */
  srandom(time(0) * getpid());
  
  /* 
  ** initalise internal rules for libinjection sqli/xss 
  ** (needs proper special scores) 
  */
  nx_int__libinject_sql = ngx_pcalloc(cf->pool, sizeof(ngx_http_rule_t));
  nx_int__libinject_xss = ngx_pcalloc(cf->pool, sizeof(ngx_http_rule_t));
  if (!nx_int__libinject_xss || !nx_int__libinject_sql) return (NGX_ERROR);
  nx_int__libinject_sql->sscores = ngx_array_create(cf->pool, 2,
						     sizeof(ngx_http_special_score_t));
  nx_int__libinject_xss->sscores = ngx_array_create(cf->pool, 2,
						    sizeof(ngx_http_special_score_t));
  if (!nx_int__libinject_sql->sscores || !nx_int__libinject_xss->sscores ) return (NGX_ERROR); /* LCOV_EXCL_LINE */
  /* internal ID sqli - 17*/
  nx_int__libinject_sql->rule_id = 17;
  /* internal ID xss - 18*/
  nx_int__libinject_xss->rule_id = 18;  
  /* libinjection sqli/xss - special score init */
  ngx_http_special_score_t *libjct_sql = ngx_array_push(nx_int__libinject_sql->sscores);
  ngx_http_special_score_t *libjct_xss = ngx_array_push(nx_int__libinject_xss->sscores);
  if (!libjct_sql || !libjct_xss) return (NGX_ERROR); /* LCOV_EXCL_LINE */
  libjct_sql->sc_tag = ngx_pcalloc(cf->pool, sizeof(ngx_str_t));
  libjct_xss->sc_tag = ngx_pcalloc(cf->pool, sizeof(ngx_str_t));
  if (!libjct_sql->sc_tag || !libjct_xss->sc_tag) return (NGX_ERROR); /* LCOV_EXCL_LINE */
  libjct_sql->sc_tag->data = ngx_pcalloc(cf->pool, 18 /* LIBINJECTION_SQL */);
  libjct_xss->sc_tag->data = ngx_pcalloc(cf->pool, 18 /* LIBINJECTION_XSS */);
  if (!libjct_sql->sc_tag->data || !libjct_xss->sc_tag->data) return (NGX_ERROR); /* LCOV_EXCL_LINE */
  strncpy((char *)libjct_sql->sc_tag->data, (char *)"$LIBINJECTION_SQL", 17);
  strncpy((char *)libjct_xss->sc_tag->data, (char *)"$LIBINJECTION_XSS", 17);
  libjct_xss->sc_tag->len = 17;
  libjct_sql->sc_tag->len = 17;
  libjct_sql->sc_score = 8;
  libjct_xss->sc_score = 8;


  return (NGX_OK);
}
Example #14
0
//#define score_debug
void	*
dummy_score(ngx_conf_t *r, ngx_str_t *tmp, ngx_http_rule_t *rule)
{
  int				score, len;
  char				*tmp_ptr, *tmp_end;
  ngx_http_special_score_t	*sc;
  
  rule->score = 0;
  rule->block = 0;
  rule->allow = 0;
  tmp_ptr = (char *) (tmp->data + strlen(SCORE_T));
#ifdef score_debug 
  ngx_conf_log_error(NGX_LOG_EMERG, r, 0,
		     "XX-(debug) dummy score (%V)",
		     tmp);
#endif
  
  /*allocate scores array*/
  if (!rule->sscores) {
    rule->sscores = ngx_array_create(r->pool, 1, sizeof(ngx_http_special_score_t));
  }

  while (*tmp_ptr) { 
    if (tmp_ptr[0] == '$') {
#ifdef score_debug 
      ngx_conf_log_error(NGX_LOG_EMERG, r, 0,
			 "XX-(debug) special scoring rule (%s)",
			 tmp_ptr);
#endif
      tmp_end = strchr(tmp_ptr, ':');
      if (!tmp_end)
	return (NGX_CONF_ERROR);
      len = tmp_end - tmp_ptr;
      if (len <= 0)
	return (NGX_CONF_ERROR);
      sc = ngx_array_push(rule->sscores);
      sc->sc_tag = ngx_pcalloc(r->pool, sizeof(ngx_str_t));
      if (!sc->sc_tag)
	return (NGX_CONF_ERROR);
      sc->sc_tag->data = ngx_pcalloc(r->pool, len+1);
      if (!sc->sc_tag->data)
	return (NGX_CONF_ERROR);
      //memset(rule->sc_tag->data, 0, len+1);
      memcpy(sc->sc_tag->data, tmp_ptr, len);
      sc->sc_tag->len = len;
      sc->sc_score = atoi(tmp_end+1);
#ifdef score_debug 
      ngx_conf_log_error(NGX_LOG_EMERG, r, 0,
			 "XX-(debug) special scoring (%V) => (%d)",
			 sc->sc_tag, sc->sc_score);
#endif
      
      /* move to end of score. */
      while ( /*don't overflow*/((unsigned int)((unsigned char *)tmp_ptr - tmp->data)) < tmp->len &&
	      /*and seek for next score */ *tmp_ptr != ',')
	++tmp_ptr;
    }
    else if (tmp_ptr[0] == ',')
      ++tmp_ptr;
    else if (!strcasecmp(tmp_ptr, "BLOCK")) {
      rule->block = 1;
      tmp_ptr += 5;
    }
    else if (!strcasecmp(tmp_ptr, "ALLOW")) {
      rule->allow = 1;
      tmp_ptr += 5;
    }
    //or maybe you just want to assign a score
    else if ( (tmp_ptr[0] >= '0' && tmp_ptr[0] <= '9') || tmp_ptr[0] == '-') {
      score = atoi((const char *)tmp->data+2);
      rule->score = score;
    }
    else
      return (NGX_CONF_ERROR);
  }
#ifdef score_debug
  unsigned int z;
  ngx_http_special_score_t	*scr;
  scr = rule->sscores->elts;
  if (rule->sscores) {
    for (z = 0; z < rule->sscores->nelts; z++) {
      ngx_conf_log_error(NGX_LOG_EMERG, r, 0,
			 "XX-score n°%d special scoring (%V) => (%d)",
			 z, scr[z].sc_tag, scr[z].sc_score);
      
    }
  }
  else
    ngx_conf_log_error(NGX_LOG_EMERG, r, 0,
		       "XX-no custom scores for this rule.");
#endif
  return (NGX_CONF_OK);
}
Example #15
0
//#define dummy_zone_debug
void	*
dummy_zone(ngx_conf_t *r, ngx_str_t *tmp, ngx_http_rule_t *rule)
{
  int					tmp_len;
  ngx_http_custom_rule_location_t	*custom_rule;
  char *tmp_ptr, *tmp_end;


  if (!rule->br)
    return (NGX_CONF_ERROR);
/* #ifdef dummy_zone_debug */
/*   ngx_conf_log_error(NGX_LOG_EMERG, r, 0, "FEU:%V", tmp); */
/* #endif   */

  
  tmp_ptr = (char *) tmp->data+strlen(MATCH_ZONE_T);
  while (*tmp_ptr) {
/* #ifdef dummy_zone_debug  */
/*     ngx_conf_log_error(NGX_LOG_EMERG, r, 0, "FEU:%s", tmp_ptr);  */
/* #endif  */
    
    if (tmp_ptr[0] == '|')
      tmp_ptr++;
    /* match global zones */
    if (!strncmp(tmp_ptr, "BODY", strlen("BODY"))) {
      rule->br->body = 1;
      tmp_ptr += strlen("BODY");
      continue;
    }
    else
      if (!strncmp(tmp_ptr, "HEADERS", strlen("HEADERS"))) {
	rule->br->headers = 1;
	tmp_ptr += strlen("HEADERS");
	continue;
      }
      else
	if (!strncmp(tmp_ptr, "URL", strlen("URL"))) {
	  rule->br->url = 1;
	  tmp_ptr += strlen("URL");
	  continue;
	}
	else
	  if (!strncmp(tmp_ptr, "ARGS", strlen("ARGS"))) {
	    rule->br->args = 1;
	    tmp_ptr += strlen("ARGS");
	    continue;
	  }
	  else
	    /* match against variable name*/
	    if (!strncmp(tmp_ptr, "NAME", strlen("NAME"))) {
	      rule->br->target_name = 1;
	      tmp_ptr += strlen("NAME");
	      continue;
	    }
	    else
	      /* for file_ext, just push'em in the body rules.
		 when multipart parsing comes in, it'll tag the zone as
		 FILE_EXT as the rule will be pushed in body rules it'll be 
		 checked !*/
	      if (!strncmp(tmp_ptr, "FILE_EXT", strlen("FILE_EXT"))) {
		rule->br->file_ext = 1;
		rule->br->body = 1;
		tmp_ptr += strlen("FILE_EXT");
		continue;
	      }
	      else
		/* custom match  zones */
#define MZ_GET_VAR_T "$ARGS_VAR:"
#define MZ_HEADER_VAR_T "$HEADERS_VAR:"
#define MZ_POST_VAR_T "$BODY_VAR:"
#define MZ_SPECIFIC_URL_T "$URL:"
		//probably a custom zone
		if (tmp_ptr[0] == '$') {
		  // tag as a custom_location rule.
		  rule->br->custom_location = 1;
		  if (!rule->br->custom_locations) {
		    rule->br->custom_locations = ngx_array_create(r->pool, 1, 
								  sizeof(ngx_http_custom_rule_location_t));
		    if (!rule->br->custom_locations)
		      return (NGX_CONF_ERROR);
		  }
		  custom_rule = ngx_array_push(rule->br->custom_locations);
		  if (!custom_rule)
		    return (NGX_CONF_ERROR);
		  memset(custom_rule, 0, sizeof(ngx_http_custom_rule_location_t));
		  if (!strncmp(tmp_ptr, MZ_GET_VAR_T, strlen(MZ_GET_VAR_T))) {
		    custom_rule->args_var = 1;
		    rule->br->args_var = 1;
		    tmp_ptr += strlen(MZ_GET_VAR_T);
		  }
		  else if (!strncmp(tmp_ptr, MZ_POST_VAR_T, 
				    strlen(MZ_POST_VAR_T))) {
		    custom_rule->body_var = 1;
		    rule->br->body_var = 1;
		    tmp_ptr += strlen(MZ_POST_VAR_T);
		  }
		  else if (!strncmp(tmp_ptr, MZ_HEADER_VAR_T, 
				    strlen(MZ_HEADER_VAR_T))) {
		    custom_rule->headers_var = 1;
		    rule->br->headers_var = 1;
		    tmp_ptr += strlen(MZ_HEADER_VAR_T);
		  }
		  else if (!strncmp(tmp_ptr, MZ_SPECIFIC_URL_T, 
				    strlen(MZ_SPECIFIC_URL_T))) { 
		    custom_rule->specific_url = 1; 
		    tmp_ptr += strlen(MZ_SPECIFIC_URL_T);
		  }
		  else 
		    return (NGX_CONF_ERROR);
		  tmp_end = strchr((const char *) tmp_ptr, '|');
		  if (!tmp_end) 
		    tmp_end = tmp_ptr + strlen(tmp_ptr);
		  tmp_len = tmp_end - tmp_ptr;
		  if (tmp_len <= 0)
		    return (NGX_CONF_ERROR);
		  custom_rule->target.data = ngx_pcalloc(r->pool, tmp_len+1);
		  if (!custom_rule->target.data)
		    return (NGX_CONF_ERROR);
		  custom_rule->target.len = tmp_len;
		  memcpy(custom_rule->target.data, tmp_ptr, tmp_len);
		  custom_rule->hash = ngx_hash_key_lc(custom_rule->target.data, 
						      custom_rule->target.len);
#ifdef dummy_zone_debug
		  ngx_conf_log_error(NGX_LOG_EMERG, r, 0, "XX- ZONE:[%V]", 
				     &(custom_rule->target));  
#endif
		  tmp_ptr += tmp_len;
		  continue;
		}
		else
		  return (NGX_CONF_ERROR);
  }
  return (NGX_CONF_OK);
}
Example #16
0
char *
ngx_http_types_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    char  *p = conf;

    ngx_array_t     **types;
    ngx_str_t        *value, *default_type;
    ngx_uint_t        i, n, hash;
    ngx_hash_key_t   *type;

    types = (ngx_array_t **) (p + cmd->offset);

    if (*types == (void *) -1) {
        return NGX_CONF_OK;
    }

    default_type = cmd->post;

    if (*types == NULL) {
        *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
        if (*types == NULL) {
            return NGX_CONF_ERROR;
        }

        if (default_type) {
            type = ngx_array_push(*types);
            if (type == NULL) {
                return NGX_CONF_ERROR;
            }

            type->key = *default_type;
            type->key_hash = ngx_hash_key(default_type->data,
                                          default_type->len);
            type->value = (void *) 4;
        }
    }

    value = cf->args->elts;

    for (i = 1; i < cf->args->nelts; i++) {

        if (value[i].len == 1 && value[i].data[0] == '*') {
            *types = (void *) -1;
            return NGX_CONF_OK;
        }

        hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
        value[i].data[value[i].len] = '\0';

        type = (*types)->elts;
        for (n = 0; n < (*types)->nelts; n++) {

            if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
                ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                                   "duplicate MIME type \"%V\"", &value[i]);
                continue;
            }
        }

        type = ngx_array_push(*types);
        if (type == NULL) {
            return NGX_CONF_ERROR;
        }

        type->key = value[i];
        type->key_hash = hash;
        type->value = (void *) 4;
    }

    return NGX_CONF_OK;
}
Example #17
0
ngx_int_t
ngx_http_echo_run_cmds(ngx_http_request_t *r)
{
    ngx_http_echo_loc_conf_t    *elcf;
    ngx_http_echo_ctx_t         *ctx;
    ngx_int_t                    rc;
    ngx_array_t                 *cmds;
    ngx_array_t                 *computed_args = NULL;
    ngx_http_echo_cmd_t         *cmd;
    ngx_http_echo_cmd_t         *cmd_elts;
    ngx_array_t                 *opts = NULL;


    elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
    cmds = elcf->handler_cmds;
    if (cmds == NULL) {
        return NGX_DECLINED;
    }

    ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
    if (ctx == NULL) {
        ctx = ngx_http_echo_create_ctx(r);
        if (ctx == NULL) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_http_set_ctx(r, ctx, ngx_http_echo_module);
    }

    dd("exec handler: %.*s: %i", (int) r->uri.len, r->uri.data,
            (int) ctx->next_handler_cmd);

    cmd_elts = cmds->elts;

    for (; ctx->next_handler_cmd < cmds->nelts; ctx->next_handler_cmd++) {

        cmd = &cmd_elts[ctx->next_handler_cmd];

        /* evaluate arguments for the current cmd (if any) */
        if (cmd->args) {
            computed_args = ngx_array_create(r->pool, cmd->args->nelts,
                    sizeof(ngx_str_t));

            if (computed_args == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            opts = ngx_array_create(r->pool, 1, sizeof(ngx_str_t));

            if (opts == NULL) {
                return NGX_HTTP_INTERNAL_SERVER_ERROR;
            }

            rc = ngx_http_echo_eval_cmd_args(r, cmd, computed_args, opts);
            if (rc != NGX_OK) {
                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "Failed to evaluate arguments for "
                        "the directive.");
                return rc;
            }
        }

        /* do command dispatch based on the opcode */
        switch (cmd->opcode) {
        case echo_opcode_echo:
            /* XXX moved the following code to a separate
             * function */
            dd("found echo opcode");
            rc = ngx_http_echo_exec_echo(r, ctx, computed_args,
                    0 /* in filter */, opts);
            break;

        case echo_opcode_echo_request_body:
            rc = ngx_http_echo_exec_echo_request_body(r, ctx);
            break;

        case echo_opcode_echo_location_async:
            dd("found opcode echo location async...");
            rc = ngx_http_echo_exec_echo_location_async(r, ctx,
                    computed_args);
            break;

        case echo_opcode_echo_location:
            return ngx_http_echo_exec_echo_location(r, ctx, computed_args);
            break;

        case echo_opcode_echo_subrequest_async:
            dd("found opcode echo subrequest async...");
            rc = ngx_http_echo_exec_echo_subrequest_async(r, ctx,
                    computed_args);
            break;

        case echo_opcode_echo_subrequest:
            return ngx_http_echo_exec_echo_subrequest(r, ctx, computed_args);
            break;

        case echo_opcode_echo_sleep:
            return ngx_http_echo_exec_echo_sleep(r, ctx, computed_args);
            break;

        case echo_opcode_echo_flush:
            rc = ngx_http_echo_exec_echo_flush(r, ctx);
            break;

        case echo_opcode_echo_blocking_sleep:
            rc = ngx_http_echo_exec_echo_blocking_sleep(r, ctx,
                    computed_args);
            break;

        case echo_opcode_echo_reset_timer:
            rc = ngx_http_echo_exec_echo_reset_timer(r, ctx);
            break;

        case echo_opcode_echo_duplicate:
            rc = ngx_http_echo_exec_echo_duplicate(r, ctx, computed_args);
            break;

        case echo_opcode_echo_read_request_body:
            ctx->wait_read_request_body = 0;

            rc = ngx_http_echo_exec_echo_read_request_body(r, ctx);

#if defined(nginx_version) && nginx_version >= 8011
            /* XXX read_client_request_body always increments the counter */
            r->main->count--;
#endif

            dd("read request body: %d", (int) rc);

            if (rc == NGX_OK) {
                continue;
            }

            ctx->wait_read_request_body = 1;

            /* r->write_event_handler = ngx_http_request_empty_handler; */

            return rc;
            break;

        case echo_opcode_echo_foreach_split:
            rc = ngx_http_echo_exec_echo_foreach_split(r, ctx, computed_args);
            break;

        case echo_opcode_echo_end:
            rc = ngx_http_echo_exec_echo_end(r, ctx);
            break;

        case echo_opcode_echo_exec:
            dd("echo_exec");
            return ngx_http_echo_exec_exec(r, ctx, computed_args);
            break;

        default:
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                    "Unknown opcode: %d", cmd->opcode);
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
            break;
        }

        if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
            return rc;
        }
    }

    rc = ngx_http_echo_send_chain_link(r, ctx, NULL /* indicate LAST */);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    return NGX_OK;
}
Example #18
0
/*
** my hugly configuration parsing function.
** should be rewritten, cause code is hugly and not bof proof at all
** does : top level parsing config function, 
**	  see foo_cfg_parse.c for stuff
*/
static char *
ngx_http_dummy_read_conf(ngx_conf_t *cf, ngx_command_t *cmd, 
			 void *conf)
{
  ngx_http_dummy_loc_conf_t	*alcf = conf, **bar;
  
  ngx_http_dummy_main_conf_t	*main_cf;
  ngx_str_t			*value;
  ngx_http_rule_t		rule, *rule_r;
  ngx_http_custom_rule_location_t	*location;
  unsigned int	i;
  

  
#ifdef _debug_readconf
  if (cf) {
    value = cf->args->elts;
    NX_LOG_DEBUG(_debug_readconf, NGX_LOG_EMERG, cf, 0, "TOP READ CONF %V %V", 
		 &(value[0]), &(value[1]));  
  }
#endif
  if (!alcf || !cf)
    return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
  value = cf->args->elts;
  main_cf = ngx_http_conf_get_module_main_conf(cf, ngx_http_naxsi_module);
  if (!alcf->pushed) { 
    bar = ngx_array_push(main_cf->locations);
    if (!bar)
      return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
    *bar = alcf;
    alcf->pushed = 1;
  }
  /*
  ** if it's a basic rule
  */
  if (!ngx_strcmp(value[0].data, TOP_BASIC_RULE_T) ||
      !ngx_strcmp(value[0].data, TOP_BASIC_RULE_N)) {
    memset(&rule, 0, sizeof(ngx_http_rule_t));
    if (ngx_http_dummy_cfg_parse_one_rule(cf, value, &rule, 
					  cf->args->nelts) != NGX_CONF_OK)
      {
	/* LCOV_EXCL_START */
	ngx_http_dummy_line_conf_error(cf, value);
	return (NGX_CONF_ERROR);
	/* LCOV_EXCL_STOP */
      }
    /* push in whitelist rules, as it have a whitelist ID array */
    if (rule.wlid_array && rule.wlid_array->nelts > 0) {
      if (alcf->whitelist_rules == NULL) {
	alcf->whitelist_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	if (alcf->whitelist_rules == NULL) {
	  return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
      }
      rule_r = ngx_array_push(alcf->whitelist_rules);
      if (!rule_r) {
	return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
      }
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* else push in appropriate ruleset : it's a normal rule */
    else {
      if (rule.br->headers) {
	if (alcf->header_rules == NULL)  {
	  alcf->header_rules = ngx_array_create(cf->pool, 2,
						sizeof(ngx_http_rule_t));
	  if (alcf->header_rules == NULL) 
	    return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
	rule_r = ngx_array_push(alcf->header_rules);
	if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in body match rules (POST/PUT) */
      if (rule.br->body || rule.br->body_var) {
	if (alcf->body_rules == NULL) {
	  alcf->body_rules = ngx_array_create(cf->pool, 2,
					      sizeof(ngx_http_rule_t));
	  if (alcf->body_rules == NULL) 
	    return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
	rule_r = ngx_array_push(alcf->body_rules);
	if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in raw body match rules (POST/PUT) */
      if (rule.br->raw_body) {
	NX_LOG_DEBUG(_debug_readconf, NGX_LOG_EMERG, cf, 0,
		 "pushing rule %d in (read conf) raw_body rules", rule.rule_id);
	if (alcf->raw_body_rules == NULL) {
	  alcf->raw_body_rules = ngx_array_create(cf->pool, 2,
						  sizeof(ngx_http_rule_t));
	  if (alcf->raw_body_rules == NULL) 
	    return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
	rule_r = ngx_array_push(alcf->raw_body_rules);
	if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in generic rules, as it's matching the URI */
      if (rule.br->url) {
	NX_LOG_DEBUG(_debug_readconf, NGX_LOG_EMERG, cf, 0,
		     "pushing rule %d in generic rules",
		     rule.rule_id);
	if (alcf->generic_rules == NULL) {
	  alcf->generic_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	  if (alcf->generic_rules == NULL) 
	    return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
	rule_r = ngx_array_push(alcf->generic_rules);
	if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in GET arg rules, but we should push in POST rules too  */
      if (rule.br->args_var || rule.br->args) {
	NX_LOG_DEBUG(_debug_readconf, NGX_LOG_EMERG, cf, 0,
		     "pushing rule %d in GET rules", rule.rule_id);
	if (alcf->get_rules == NULL) {
	  alcf->get_rules = ngx_array_create(cf->pool, 2,
					     sizeof(ngx_http_rule_t));
	  if (alcf->get_rules == NULL) 
	    return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	}
	rule_r = ngx_array_push(alcf->get_rules);
	if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
      }
      /* push in custom locations. It's a rule matching a VAR_NAME or an EXACT_URI :
	 - GET_VAR, POST_VAR, URI */
      if (rule.br->custom_location) {
	NX_LOG_DEBUG(_debug_readconf, NGX_LOG_EMERG, cf, 0, 
		     "pushing rule %d in custom_location rules", 
		     rule.rule_id);  
	location = rule.br->custom_locations->elts;
	for (i = 0; i < rule.br->custom_locations->nelts; i++) {
	  if (location[i].args_var) {
	    if (alcf->get_rules == NULL) {
	      alcf->get_rules = ngx_array_create(cf->pool, 2,
						 sizeof(ngx_http_rule_t));
	      if (alcf->get_rules == NULL) 
		return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	    }
	    rule_r = ngx_array_push(alcf->get_rules);
	    if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	  }
	  if (location[i].body_var) {
	    if (alcf->body_rules == NULL) {
	      alcf->body_rules = ngx_array_create(cf->pool, 2,
						  sizeof(ngx_http_rule_t));
	      if (alcf->body_rules == NULL) 
		return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	    }
	    rule_r = ngx_array_push(alcf->body_rules);
	    if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
		      
	  }
	  if (location[i].headers_var) {
	    if (alcf->header_rules == NULL) {
	      alcf->header_rules = ngx_array_create(cf->pool, 2,
						    sizeof(ngx_http_rule_t));
	      if (alcf->header_rules == NULL) 
		return NGX_CONF_ERROR; /* LCOV_EXCL_LINE */
	    }
	    rule_r = ngx_array_push(alcf->header_rules);
	    if (!rule_r) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
	    memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	  }
	}
      }
    }
    return (NGX_CONF_OK);
  }
  ngx_http_dummy_line_conf_error(cf, value);
  return (NGX_CONF_ERROR);
}
static char *
ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_headers_conf_t *hcf = conf;

    ngx_int_t                   n;
    ngx_str_t                  *value;
    ngx_uint_t                  i;
    ngx_http_header_val_t      *h;
    ngx_http_set_header_t      *sh;
    ngx_http_script_compile_t   sc;

    value = cf->args->elts;

    if (hcf->headers == NULL) {
        hcf->headers = ngx_array_create(cf->pool, 1,
                                        sizeof(ngx_http_header_val_t));
        if (hcf->headers == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    h = ngx_array_push(hcf->headers);
    if (h == NULL) {
        return NGX_CONF_ERROR;
    }

    h->value.hash = 1;
    h->value.key = value[1];
    h->value.value = value[2];
    h->offset = 0;
    h->handler = ngx_http_add_header;
    h->lengths = NULL;
    h->values = NULL;

    sh = ngx_http_set_headers;
    for (i = 0; sh[i].name.len; i++) {
        if (ngx_strcasecmp(value[1].data, sh[i].name.data) != 0) {
            continue;
        }

        h->offset = sh[i].offset;
        h->handler = sh[i].handler;
        break;
    }

    n = ngx_http_script_variables_count(&value[2]);

    if (n == 0) {
        return NGX_CONF_OK;
    }

    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

    sc.cf = cf;
    sc.source = &value[2];
    sc.lengths = &h->lengths;
    sc.values = &h->values;
    sc.variables = n;
    sc.complete_lengths = 1;
    sc.complete_values = 1;

    if (ngx_http_script_compile(&sc) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

    return NGX_CONF_OK;
}
Example #20
0
static char *
ngx_http_naxsi_cr_loc_conf(ngx_conf_t *cf, ngx_command_t *cmd,
			   void *conf)
{

  ngx_http_dummy_loc_conf_t	*alcf = conf, **bar;  
  ngx_http_dummy_main_conf_t    *main_cf;
  ngx_str_t			*value;
  ngx_http_check_rule_t		*rule_c;
  unsigned int	i;
  u_char			*var_end;

  

  if (!alcf || !cf)
    return (NGX_CONF_ERROR); 
  value = cf->args->elts;
  main_cf = ngx_http_conf_get_module_main_conf(cf, ngx_http_naxsi_module);
  if (!alcf->pushed) { 
    bar = ngx_array_push(main_cf->locations);
    if (!bar)
      return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
    *bar = alcf;
    alcf->pushed = 1;
  }
  
  if (ngx_strcmp(value[0].data, TOP_CHECK_RULE_T) &&
      ngx_strcmp(value[0].data, TOP_CHECK_RULE_N))
    return (NGX_CONF_ERROR);
  
/* #ifdef _debug_readconf */
/*   ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,  */
/* 		     "pushing rule %d in check rules", rule.rule_id);   */
/* #endif */

  i = 0;
  if (!alcf->check_rules)
    alcf->check_rules = ngx_array_create(cf->pool, 2, 
					 sizeof(ngx_http_check_rule_t));
  if (!alcf->check_rules)
    return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
  rule_c = ngx_array_push(alcf->check_rules);
  if (!rule_c) return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
  memset(rule_c, 0, sizeof(ngx_http_check_rule_t));
  /* process the first word : score rule */
  if (value[1].data[i] == '$') {
    var_end = (u_char *) ngx_strchr((value[1].data)+i, ' ');
    if (!var_end) { /* LCOV_EXCL_START */
      ngx_http_dummy_line_conf_error(cf, value);
      return (NGX_CONF_ERROR);
      /* LCOV_EXCL_STOP */
    }
    rule_c->sc_tag.len = var_end - value[1].data;
    rule_c->sc_tag.data = ngx_pcalloc(cf->pool, rule_c->sc_tag.len + 1);
    if (!rule_c->sc_tag.data)
      return (NGX_CONF_ERROR); /* LCOV_EXCL_LINE */
    memcpy(rule_c->sc_tag.data, value[1].data, rule_c->sc_tag.len);
    i += rule_c->sc_tag.len + 1;
  } else {
    /* LCOV_EXCL_START */
    ngx_http_dummy_line_conf_error(cf, value);
    return (NGX_CONF_ERROR); 
    /* LCOV_EXCL_STOP */
  }
  // move to next word
  while (value[1].data[i] && value[1].data[i] == ' ')
    i++;
  // get the comparison type
  if (value[1].data[i] == '>' && value[1].data[i+1] == '=')
    rule_c->cmp = SUP_OR_EQUAL;
  else if (value[1].data[i] == '>' && value[1].data[i+1] != '=')
    rule_c->cmp = SUP;
  else if (value[1].data[i] == '<' && value[1].data[i+1] == '=')
    rule_c->cmp = INF_OR_EQUAL;
  else if (value[1].data[i] == '<' && value[1].data[i+1] != '=')
    rule_c->cmp = INF;
  else {
    ngx_http_dummy_line_conf_error(cf, value);
    return (NGX_CONF_ERROR);
  }
  // move to next word
  while (value[1].data[i] && !(value[1].data[i] >= '0' && 
			       value[1].data[i] <= '9') && (value[1].data[i] != '-'))
    i++;
  NX_LOG_DEBUG(_debug_readconf,  NGX_LOG_EMERG, cf, 0,
	       "XX-special score in checkrule:%s from (%d)",
	       value[1].data, atoi((const char *)value[1].data+i));
  // get the score
  rule_c->sc_score = atoi((const char *)(value[1].data+i));
  /* process the second word : Action rule */
  if (ngx_strstr(value[2].data, "BLOCK"))
    rule_c->block = 1;
  else if (ngx_strstr(value[2].data,"ALLOW"))
    rule_c->allow = 1;
  else if (ngx_strstr(value[2].data, "LOG"))
    rule_c->log = 1;
  else if (ngx_strstr(value[2].data, "DROP"))
    rule_c->drop = 1;
  else {
    /* LCOV_EXCL_START */
    ngx_http_dummy_line_conf_error(cf, value);
    return (NGX_CONF_ERROR);
    /* LCOV_EXCL_STOP */
  }
  return (NGX_CONF_OK);
}
Example #21
0
static ngx_int_t
ngx_http_ssl_compile_certificates(ngx_conf_t *cf,
    ngx_http_ssl_srv_conf_t *conf)
{
    ngx_str_t                         *cert, *key;
    ngx_uint_t                         i, nelts;
    ngx_http_complex_value_t          *cv;
    ngx_http_compile_complex_value_t   ccv;

    cert = conf->certificates->elts;
    key = conf->certificate_keys->elts;
    nelts = conf->certificates->nelts;

    for (i = 0; i < nelts; i++) {

        if (ngx_http_script_variables_count(&cert[i])) {
            goto found;
        }

        if (ngx_http_script_variables_count(&key[i])) {
            goto found;
        }
    }

    return NGX_OK;

found:

    conf->certificate_values = ngx_array_create(cf->pool, nelts,
                                             sizeof(ngx_http_complex_value_t));
    if (conf->certificate_values == NULL) {
        return NGX_ERROR;
    }

    conf->certificate_key_values = ngx_array_create(cf->pool, nelts,
                                             sizeof(ngx_http_complex_value_t));
    if (conf->certificate_key_values == NULL) {
        return NGX_ERROR;
    }

    for (i = 0; i < nelts; i++) {

        cv = ngx_array_push(conf->certificate_values);
        if (cv == NULL) {
            return NGX_ERROR;
        }

        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

        ccv.cf = cf;
        ccv.value = &cert[i];
        ccv.complex_value = cv;
        ccv.zero = 1;

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

        cv = ngx_array_push(conf->certificate_key_values);
        if (cv == NULL) {
            return NGX_ERROR;
        }

        ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));

        ccv.cf = cf;
        ccv.value = &key[i];
        ccv.complex_value = cv;
        ccv.zero = 1;

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

    conf->passwords = ngx_ssl_preserve_passwords(cf, conf->passwords);
    if (conf->passwords == NULL) {
        return NGX_ERROR;
    }

    return NGX_OK;
}
static char *ngx_http_upstream_resolveMK(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf)
{
	ngx_http_upstream_srv_conf_t *uscf;
	ngx_http_upstream_resolveMK_srv_conf_t *urcf;
	ngx_http_upstream_server_t *us;

	time_t interval;
	ngx_str_t *value, domain, s;
	ngx_int_t max_ip;
	ngx_uint_t retry;
	ngx_http_upstream_resolveMK_peer_t *paddr;
	ngx_url_t u;
	ngx_uint_t i;

	interval = 10;
	max_ip = 20;
	retry = 1;
	domain.data = NULL;
	domain.len = 0;
	uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);

	/* Just For Padding, upstream { } need it */
	if (uscf->servers == NULL) {
		uscf->servers = ngx_array_create(cf->pool, 1,
		                                 sizeof(ngx_http_upstream_server_t));

		if (uscf->servers == NULL) {
			return NGX_CONF_ERROR;
		}
	}

	us = ngx_array_push(uscf->servers);

	if (us == NULL) {
		return NGX_CONF_ERROR;
	}

	ngx_memzero(us, sizeof(ngx_http_upstream_server_t));
	urcf = ngx_http_conf_upstream_srv_conf(uscf,
	                                       ngx_http_upstream_resolveMK_module);
	uscf->peer.init_upstream = ngx_http_upstream_resolveMK_init;
	value = cf->args->elts;

	if (value[1].len == 0) {
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
		                   "domain is not given");

		return NGX_CONF_ERROR;
	}

	domain.data = value[1].data;
	domain.len  = value[1].len;

	if (ngx_strncmp(value[2].data, "service=", 8) != 0) {
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
		                   "service is not given");

		return NGX_CONF_ERROR;
	}

	urcf->resolver_service.len = value[2].len - 8;
	urcf->resolver_service.data = &value[2].data[8];

	for (i = 3; i < cf->args->nelts; i++) {

		if (ngx_strncmp(value[i].data, "interval=", 9) == 0) {
			s.len = value[i].len - 9;
			s.data = &value[i].data[9];
			interval = ngx_parse_time(&s, 1);

			if (interval == (time_t) NGX_ERROR) {
				goto invalid;
			}

			continue;
		}

		if (ngx_strncmp(value[i].data, "max_ip=", 7) == 0) {
			max_ip = ngx_atoi(value[i].data + 7, value[i].len - 7);

			if (max_ip == NGX_ERROR || max_ip < 1) {
				goto invalid;
			}

			continue;
		}

		if (ngx_strncmp(value[i].data, "retry_off", 9) == 0) {
			retry = 0;
			continue;
		}

		goto invalid;
	}

	urcf->peers = ngx_pcalloc(cf->pool,
	                          max_ip * sizeof(ngx_http_upstream_resolveMK_peer_t));

	if (urcf->peers == NULL) {
		ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
		                   "ngx_palloc peers fail");
		return NGX_CONF_ERROR;
	}

	urcf->resolver_interval = interval;
	urcf->resolver_domain = domain;
	urcf->resolver_max_ip = max_ip;
	urcf->upstream_retry = retry;
	ngx_memzero(&u, sizeof(ngx_url_t));
	u.url = value[1];

	if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
		if (u.err) {
			ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			                   "%s in upstream \"%V\"", u.err, &u.url);
		}

		return NGX_CONF_ERROR;
	}

	urcf->resolved_num = 0;

	for (i = 0; i < u.naddrs ; i++) {
		paddr = &urcf->peers[urcf->resolved_num];
		paddr->sockaddr = *(struct sockaddr*)u.addrs[i].sockaddr;
		paddr->socklen = u.addrs[i].socklen;
		paddr->name = u.addrs[i].name;
		urcf->resolved_num++;

		if (urcf->resolved_num >= urcf->resolver_max_ip) {
			break;
		}
	}

	/* urcf->resolved_index = 0 */
	urcf->resolved_access = ngx_time();

	return NGX_CONF_OK;
invalid:
	ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
	                   "invalid parameter \"%V\"", &value[i]);

	return NGX_CONF_ERROR;
}
static char *
ngx_http_headers_more_parse_directive(ngx_conf_t *cf, ngx_command_t *ngx_cmd,
        void *conf, ngx_http_headers_more_opcode_t opcode)
{
    ngx_http_headers_more_loc_conf_t   *hcf = conf;

    ngx_uint_t                          i;
    ngx_http_headers_more_cmd_t         *cmd;
    ngx_str_t                           *arg;
    ngx_flag_t                          ignore_next_arg;
    ngx_str_t                           *cmd_name;
    ngx_int_t                           rc;
    ngx_flag_t                          replace = 0;
    ngx_http_headers_more_header_val_t  *h;

    if (hcf->cmds == NULL) {
        hcf->cmds = ngx_array_create(cf->pool, 1,
                        sizeof(ngx_http_headers_more_cmd_t));

        if (hcf->cmds == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    cmd = ngx_array_push(hcf->cmds);

    if (cmd == NULL) {
        return NGX_CONF_ERROR;
    }

    cmd->headers = ngx_array_create(cf->pool, 1,
                            sizeof(ngx_http_headers_more_header_val_t));

    if (cmd->headers == NULL) {
        return NGX_CONF_ERROR;
    }

    cmd->types = ngx_array_create(cf->pool, 1,
                            sizeof(ngx_str_t));
    if (cmd->types == NULL) {
        return NGX_CONF_ERROR;
    }

    cmd->statuses = NULL;

    arg = cf->args->elts;

    cmd_name = &arg[0];

    ignore_next_arg = 0;

    for (i = 1; i < cf->args->nelts; i++) {
        if (ignore_next_arg) {
            ignore_next_arg = 0;
            continue;
        }

        if (arg[i].len == 0) {
            continue;
        }

        if (arg[i].data[0] != '-') {
            rc = ngx_http_headers_more_parse_header(cf, cmd_name,
                    &arg[i], cmd->headers, opcode,
                    ngx_http_headers_more_set_handlers);

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

            continue;
        }

        if (arg[i].len == 2) {
            if (arg[i].data[1] == 't') {
                if (i == cf->args->nelts - 1) {
                    ngx_log_error(NGX_LOG_ERR, cf->log, 0,
                          "%V: option -t takes an argument.",
                          cmd_name);

                    return NGX_CONF_ERROR;
                }

                rc = ngx_http_headers_more_parse_types(cf->log, cmd_name,
                        &arg[i + 1], cmd->types);

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

                ignore_next_arg = 1;

                continue;
            } else if (arg[i].data[1] == 'r') {
              dd("Found replace flag");
              replace = 1;
              continue;
            }
        }

        ngx_log_error(NGX_LOG_ERR, cf->log, 0,
                      "%V: invalid option name: \"%V\"", cmd_name, &arg[i]);

        return NGX_CONF_ERROR;
    }

    dd("Found %d types, and %d headers",
            (int) cmd->types->nelts,
            (int) cmd->headers->nelts);

    if (cmd->headers->nelts == 0) {
        ngx_pfree(cf->pool, cmd->headers);
        cmd->headers = NULL;

    } else {
        h = cmd->headers->elts;
        for (i = 0; i < cmd->headers->nelts; i++) {
            h[i].replace = replace;
        }
    }

    if (cmd->types->nelts == 0) {
        ngx_pfree(cf->pool, cmd->types);
        cmd->types = NULL;
    }

    cmd->is_input = 1;

    ngx_http_headers_more_handler_used = 1;

    return NGX_CONF_OK;
}
char *
ngx_http_cache_purge_conf(ngx_conf_t *cf, ngx_http_cache_purge_conf_t *cpcf)
{
    ngx_cidr_t       cidr;
    ngx_in_cidr_t   *access;
# if (NGX_HAVE_INET6)
    ngx_in6_cidr_t  *access6;
# endif /* NGX_HAVE_INET6 */
    ngx_str_t       *value;
    ngx_int_t        rc;
    ngx_uint_t       i;

    value = cf->args->elts;

    if (ngx_strcmp(value[1].data, "off") == 0) {
        cpcf->enable = 0;
        return NGX_CONF_OK;

    } else if (ngx_strcmp(value[1].data, "on") == 0) {
        ngx_str_set(&cpcf->method, "PURGE");

    } else {
        cpcf->method = value[1];
    }

    if (cf->args->nelts < 4) {
        cpcf->enable = 1;
        return NGX_CONF_OK;
    }

    /* sanity check */
    if (ngx_strcmp(value[2].data, "from") != 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "invalid parameter \"%V\", expected"
                           " \"from\" keyword", &value[2]);
        return NGX_CONF_ERROR;
    }

    if (ngx_strcmp(value[3].data, "all") == 0) {
        cpcf->enable = 1;
        return NGX_CONF_OK;
    }

    for (i = 3; i < cf->args->nelts; i++) {
        rc = ngx_ptocidr(&value[i], &cidr);

        if (rc == NGX_ERROR) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "invalid parameter \"%V\"", &value[i]);
            return NGX_CONF_ERROR;
        }

        if (rc == NGX_DONE) {
            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                               "low address bits of %V are meaningless",
                               &value[i]);
        }

        switch (cidr.family) {
        case AF_INET:
            if (cpcf->access == NULL) {
                cpcf->access = ngx_array_create(cf->pool, cf->args->nelts - 3,
                                                sizeof(ngx_in_cidr_t));
                if (cpcf->access == NULL) {
                    return NGX_CONF_ERROR;
                }
            }

            access = ngx_array_push(cpcf->access);
            if (access == NULL) {
                return NGX_CONF_ERROR;
            }

            access->mask = cidr.u.in.mask;
            access->addr = cidr.u.in.addr;

            break;

# if (NGX_HAVE_INET6)
        case AF_INET6:
            if (cpcf->access6 == NULL) {
                cpcf->access6 = ngx_array_create(cf->pool, cf->args->nelts - 3,
                                                 sizeof(ngx_in6_cidr_t));
                if (cpcf->access6 == NULL) {
                    return NGX_CONF_ERROR;
                }
            }

            access6 = ngx_array_push(cpcf->access6);
            if (access6 == NULL) {
                return NGX_CONF_ERROR;
            }

            access6->mask = cidr.u.in6.mask;
            access6->addr = cidr.u.in6.addr;

            break;
# endif /* NGX_HAVE_INET6 */
        }
    }

    cpcf->enable = 1;

    return NGX_CONF_OK;
}
/*
 * Based on: ngx_http_upstream.c/ngx_http_upstream_server
 * Copyright (C) Igor Sysoev
 */
char *
ngx_postgres_conf_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t                         *value = cf->args->elts;
    ngx_postgres_upstream_srv_conf_t  *pgscf = conf;
    ngx_postgres_upstream_server_t    *pgs;
    ngx_http_upstream_srv_conf_t      *uscf;
    ngx_url_t                          u;
    ngx_uint_t                         i;

    dd("entering");

    uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);

    if (pgscf->servers == NULL) {
        pgscf->servers = ngx_array_create(cf->pool, 4,
                             sizeof(ngx_postgres_upstream_server_t));
        if (pgscf->servers == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        uscf->servers = pgscf->servers;
    }

    pgs = ngx_array_push(pgscf->servers);
    if (pgs == NULL) {
        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    ngx_memzero(pgs, sizeof(ngx_postgres_upstream_server_t));

    /* parse the first name:port argument */

    ngx_memzero(&u, sizeof(ngx_url_t));

    u.url = value[1];
    u.default_port = 5432; /* PostgreSQL default */

    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
        if (u.err) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                               "postgres: %s in upstream \"%V\"",
                               u.err, &u.url);
        }

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    pgs->addrs = u.addrs;
    pgs->naddrs = u.naddrs;
    pgs->port = u.port;

    /* parse various options */
    for (i = 2; i < cf->args->nelts; i++) {

        if (ngx_strncmp(value[i].data, "dbname=", sizeof("dbname=") - 1)
                == 0)
        {
            pgs->dbname.len = value[i].len - (sizeof("dbname=") - 1);
            pgs->dbname.data = &value[i].data[sizeof("dbname=") - 1];
            continue;
        }

        if (ngx_strncmp(value[i].data, "user="******"user="******"user="******"user="******"password="******"password="******"password="******"password="******"postgres: invalid parameter \"%V\" in"
                           " \"postgres_server\"", &value[i]);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    uscf->peer.init_upstream = ngx_postgres_upstream_init;

    dd("returning NGX_CONF_OK");
    return NGX_CONF_OK;
}
static char *
ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_access_loc_conf_t *alcf = conf;

    ngx_int_t                 rc;
    ngx_uint_t                all;
    ngx_str_t                *value;
    ngx_cidr_t                cidr;
    ngx_http_access_rule_t   *rule;
#if (NGX_HAVE_INET6)
    ngx_http_access_rule6_t  *rule6;
#endif

    ngx_memzero(&cidr, sizeof(ngx_cidr_t));

    value = cf->args->elts;

    all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0);

    if (!all) {

        rc = ngx_ptocidr(&value[1], &cidr);

        if (rc == NGX_ERROR) {
            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                         "invalid parameter \"%V\"", &value[1]);
            return NGX_CONF_ERROR;
        }

        if (rc == NGX_DONE) {
            ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
                         "low address bits of %V are meaningless", &value[1]);
        }
    }

    switch (cidr.family) {

#if (NGX_HAVE_INET6)
    case AF_INET6:
    case 0: /* all */

        if (alcf->rules6 == NULL) {
            alcf->rules6 = ngx_array_create(cf->pool, 4,
                                            sizeof(ngx_http_access_rule6_t));
            if (alcf->rules6 == NULL) {
                return NGX_CONF_ERROR;
            }
        }

        rule6 = ngx_array_push(alcf->rules6);
        if (rule6 == NULL) {
            return NGX_CONF_ERROR;
        }

        rule6->mask = cidr.u.in6.mask;
        rule6->addr = cidr.u.in6.addr;
        rule6->deny = (value[0].data[0] == 'd') ? 1 : 0;

        if (!all) {
            break;
        }

        /* "all" passes through */
#endif

    default: /* AF_INET */

        if (alcf->rules == NULL) {
            alcf->rules = ngx_array_create(cf->pool, 4,
                                           sizeof(ngx_http_access_rule_t));
            if (alcf->rules == NULL) {
                return NGX_CONF_ERROR;
            }
        }

        rule = ngx_array_push(alcf->rules);
        if (rule == NULL) {
            return NGX_CONF_ERROR;
        }

        rule->mask = cidr.u.in.mask;
        rule->addr = cidr.u.in.addr;
        rule->deny = (value[0].data[0] == 'd') ? 1 : 0;
    }

    return NGX_CONF_OK;
}
char *
ngx_postgres_conf_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t                    *value = cf->args->elts;
    ngx_str_t                     what = value[cf->args->nelts - 2];
    ngx_str_t                     to = value[cf->args->nelts - 1];
    ngx_postgres_loc_conf_t      *pglcf = conf;
    ngx_postgres_rewrite_conf_t  *pgrcf;
    ngx_postgres_rewrite_t       *rewrite;
    ngx_postgres_rewrite_enum_t  *e;
    ngx_conf_bitmask_t           *b;
    ngx_uint_t                    methods, keep_body, i, j;

    dd("entering");

    e = ngx_postgres_rewrite_handlers;
    for (i = 0; e[i].name.len; i++) {
        if ((e[i].name.len == what.len)
            && (ngx_strcasecmp(e[i].name.data, what.data) == 0))
        {
            break;
        }
    }

    if (e[i].name.len == 0) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: invalid condition \"%V\""
                           " in \"%V\" directive", &what, &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    if (pglcf->rewrites == NGX_CONF_UNSET_PTR) {
        pglcf->rewrites = ngx_array_create(cf->pool, 2,
                                           sizeof(ngx_postgres_rewrite_conf_t));
        if (pglcf->rewrites == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }
    } else {
        pgrcf = pglcf->rewrites->elts;
        for (j = 0; j < pglcf->rewrites->nelts; j++) {
            if (pgrcf[j].key == e[i].key) {
                pgrcf = &pgrcf[j];
                goto found;
            }
        }
    }

    pgrcf = ngx_array_push(pglcf->rewrites);
    if (pgrcf == NULL) {
        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    ngx_memzero(pgrcf, sizeof(ngx_postgres_rewrite_conf_t));

    pgrcf->key = e[i].key;
    pgrcf->handler = e[i].handler;

found:
    if (cf->args->nelts == 3) {
        /* default rewrite */
        dd("default rewrite");

        if (pgrcf->def != NULL) {
            dd("returning");
            return "is duplicate";
        }

        pgrcf->def = ngx_palloc(cf->pool, sizeof(ngx_postgres_rewrite_t));
        if (pgrcf->def == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        methods = 0xFFFF;
        rewrite = pgrcf->def;
    } else {
        /* method-specific rewrite */
        dd("method-specific rewrite");

        methods = 0;

        for (i = 1; i < cf->args->nelts - 2; i++) {
            b = ngx_postgres_http_methods;
            for (j = 0; b[j].name.len; j++) {
                if ((b[j].name.len == value[i].len)
                    && (ngx_strcasecmp(b[j].name.data, value[i].data) == 0))
                {
                    if (pgrcf->methods_set & b[j].mask) {
                        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                           "postgres: method \"%V\" for"
                                           " condition \"%V\" is duplicate"
                                           " in \"%V\" directive",
                                           &value[i], &what, &cmd->name);

                        dd("returning NGX_CONF_ERROR");
                        return NGX_CONF_ERROR;
                    }

                    methods |= b[j].mask;
                    break;
                }
            }

            if (b[j].name.len == 0) {
                ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                   "postgres: invalid method \"%V\" for"
                                   " condition \"%V\" in \"%V\" directive",
                                   &value[i], &what, &cmd->name);

                dd("returning NGX_CONF_ERROR");
                return NGX_CONF_ERROR;
            }
        }

        if (pgrcf->methods == NULL) {
            pgrcf->methods = ngx_array_create(cf->pool, 4,
                                              sizeof(ngx_postgres_rewrite_t));
            if (pgrcf->methods == NULL) {
                dd("returning NGX_CONF_ERROR");
                return NGX_CONF_ERROR;
            }
        }

        rewrite = ngx_array_push(pgrcf->methods);
        if (rewrite == NULL) {
            dd("returning NGX_CONF_ERROR");
            return NGX_CONF_ERROR;
        }

        pgrcf->methods_set |= methods;
    }

    if (to.data[0] == '=') {
        keep_body = 1;
        to.len--;
        to.data++;
    } else {
        keep_body = 0;
    }

    rewrite->key = methods;
    rewrite->status = ngx_atoi(to.data, to.len);
    if ((rewrite->status == NGX_ERROR)
        || (rewrite->status < NGX_HTTP_OK)
        || (rewrite->status > NGX_HTTP_INSUFFICIENT_STORAGE)
        || ((rewrite->status >= NGX_HTTP_SPECIAL_RESPONSE)
            && (rewrite->status < NGX_HTTP_BAD_REQUEST)))
    {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                           "postgres: invalid status value \"%V\" for"
                           " condition \"%V\" in \"%V\" directive",
                           &to, &what, &cmd->name);

        dd("returning NGX_CONF_ERROR");
        return NGX_CONF_ERROR;
    }

    if (keep_body) {
        rewrite->status = -rewrite->status;
    }

    dd("returning NGX_CONF_OK");
    return NGX_CONF_OK;
}
static char *
ngx_http_subs_filter( ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_int_t                   n;
    ngx_uint_t                  i;
    ngx_str_t                  *value;
    ngx_str_t                  *option;
    sub_pair_t                 *pair;
    ngx_http_subs_loc_conf_t   *slcf = conf;
    ngx_http_script_compile_t   sc;

    value = cf->args->elts;

    if (slcf->sub_pairs == NULL) {
        slcf->sub_pairs = ngx_array_create(cf->pool, 4, sizeof(sub_pair_t));
        if (slcf->sub_pairs == NULL) {
            return NGX_CONF_ERROR;
        }
    }

    pair = ngx_array_push(slcf->sub_pairs);
    if (pair == NULL) {
        return NGX_CONF_ERROR;
    }
    ngx_memzero(pair, sizeof(sub_pair_t));

    pair->match = value[1];

    n = ngx_http_script_variables_count(&value[2]);
    if (n != 0) {
        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));

        sc.cf = cf;
        sc.source = &value[2];
        sc.lengths = &pair->sub_lengths;
        sc.values = &pair->sub_values;
        sc.variables = n;
        sc.complete_lengths = 1;
        sc.complete_values = 1;

        if (ngx_http_script_compile(&sc) != NGX_OK) {
            return NGX_CONF_ERROR;
        }

        /* Dirty hack, if it has captured variables */
        if (sc.captures_mask) {
            pair->has_captured = 1;
        }

    } else {
        pair->sub = value[2];
    }

    if (cf->args->nelts > 3) {
        option = &value[3];
        for(i = 0; i < option->len; i++) {

            switch (option->data[i]){
            case 'i':
                pair->insensitive = 1;
                break;

            case 'o':
                pair->once = 1;
                break;

            case 'r':
                pair->regex = 1;
                break;

            case 'g':
            default:
                continue;
            }
        }
    }

    if (pair->regex || pair->insensitive) {
        if (ngx_http_subs_filter_regex_compile(pair, &sc, cf) == NGX_ERROR) {
            return NGX_CONF_ERROR;
        }
    }

    return NGX_CONF_OK;
}
//#define main_conf_debug
static char *
ngx_http_dummy_read_main_conf(ngx_conf_t *cf, ngx_command_t *cmd, 
			      void *conf)
{
  ngx_http_dummy_main_conf_t	*alcf = conf;
  ngx_str_t			*value;
  ngx_http_rule_t		rule, *rule_r;
  ngx_http_custom_rule_location_t	*location;
  unsigned int	i;
  if (!alcf || !cf)
    return (NGX_CONF_ERROR);  /* alloc a new rule */
  value = cf->args->elts;
  /* parse the line, fill rule struct  */
#ifdef main_conf_debug
  ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
		     "XX-TOP READ CONF %s", value[0].data);
#endif
  if (!ngx_strcmp(value[0].data, TOP_MAIN_BASIC_RULE_T)) {
    memset(&rule, 0, sizeof(ngx_http_rule_t));
    if (ngx_http_dummy_cfg_parse_one_rule(cf/*, alcf*/, value, &rule, 
					  cf->args->nelts) != NGX_CONF_OK) {
      ngx_http_dummy_line_conf_error(cf, value);
      return (NGX_CONF_ERROR);
    }

    if (rule.br->headers) {
#ifdef main_conf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "pushing rule %d in header rules", rule.rule_id);  
#endif
      if (alcf->header_rules == NULL) {
	alcf->header_rules = ngx_array_create(cf->pool, 2,
					      sizeof(ngx_http_rule_t));
	if (alcf->header_rules == NULL) 
	  return NGX_CONF_ERROR;
      }
      rule_r = ngx_array_push(alcf->header_rules);
      if (!rule_r) return (NGX_CONF_ERROR);
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* push in body match rules (POST/PUT) */
    if (rule.br->body || rule.br->body_var) {
#ifdef main_conf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "pushing rule %d in body rules", rule.rule_id);  
#endif
      if (alcf->body_rules == NULL) {
	alcf->body_rules = ngx_array_create(cf->pool, 2,
					    sizeof(ngx_http_rule_t));
	if (alcf->body_rules == NULL) 
	  return NGX_CONF_ERROR;
      }
      rule_r = ngx_array_push(alcf->body_rules);
      if (!rule_r) return (NGX_CONF_ERROR);
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* push in generic rules, as it's matching the URI */
    if (rule.br->url)	{
#ifdef main_conf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
			 "pushing rule %d in generic rules", rule.rule_id);  
#endif
      if (alcf->generic_rules == NULL) {
	alcf->generic_rules = ngx_array_create(cf->pool, 2,
					       sizeof(ngx_http_rule_t));
	if (alcf->generic_rules == NULL) 
	  return NGX_CONF_ERROR;
      }
      rule_r = ngx_array_push(alcf->generic_rules);
      if (!rule_r) return (NGX_CONF_ERROR);
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* push in GET arg rules, but we should push in POST rules too  */
    if (rule.br->args_var || rule.br->args) {
#ifdef main_conf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "pushing rule %d in GET rules", rule.rule_id);  
#endif
      if (alcf->get_rules == NULL) {
	alcf->get_rules = ngx_array_create(cf->pool, 2,
					   sizeof(ngx_http_rule_t));
	if (alcf->get_rules == NULL) 
	  return NGX_CONF_ERROR;
      }
      rule_r = ngx_array_push(alcf->get_rules);
      if (!rule_r) return (NGX_CONF_ERROR);
      memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
    }
    /* push in custom locations. It's a rule matching a VAR_NAME or an EXACT_URI :
       - GET_VAR, POST_VAR, URI */
    if (rule.br->custom_location) {
#ifdef main_conf_debug
      ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 
			 "pushing rule %d in custom_location rules", 
			 rule.rule_id);  
#endif
      location = rule.br->custom_locations->elts;
      for (i = 0; i < rule.br->custom_locations->nelts; i++) {
	if (location[i].args_var)	{
	  if (alcf->get_rules == NULL) {
	    alcf->get_rules = ngx_array_create(cf->pool, 2,
					       sizeof(ngx_http_rule_t));
	    if (alcf->get_rules == NULL) 
	      return NGX_CONF_ERROR;
	  }
	  rule_r = ngx_array_push(alcf->get_rules);
	  if (!rule_r) return (NGX_CONF_ERROR);
	  memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	}
	if (location[i].body_var)	{
	  if (alcf->body_rules == NULL) {
	    alcf->body_rules = ngx_array_create(cf->pool, 2,
						sizeof(ngx_http_rule_t));
	    if (alcf->body_rules == NULL) 
	      return NGX_CONF_ERROR;
	  }
	  rule_r = ngx_array_push(alcf->body_rules);
	  if (!rule_r) return (NGX_CONF_ERROR);
	  memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
		      
	}
	if (location[i].headers_var) {
	  if (alcf->header_rules == NULL) {
	    alcf->header_rules = ngx_array_create(cf->pool, 2,
						  sizeof(ngx_http_rule_t));
	    if (alcf->header_rules == NULL) 
	      return NGX_CONF_ERROR;
	  }
	  rule_r = ngx_array_push(alcf->header_rules);
	  if (!rule_r) return (NGX_CONF_ERROR);
	  memcpy(rule_r, &rule, sizeof(ngx_http_rule_t));
	}
      }
    }
    return (NGX_CONF_OK);
  }
  ngx_http_dummy_line_conf_error(cf, value);
  return (NGX_CONF_ERROR);
}
Example #30
0
ngx_int_t
ngx_http_add_listen(ngx_conf_t *cf, ngx_http_core_srv_conf_t *cscf,
    ngx_http_listen_opt_t *lsopt)
{
    in_port_t                   p;
    ngx_uint_t                  i;
    struct sockaddr            *sa;
    struct sockaddr_in         *sin;
    ngx_http_conf_port_t       *port;
    ngx_http_core_main_conf_t  *cmcf;
#if (NGX_HAVE_INET6)
    struct sockaddr_in6        *sin6;
#endif

    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

    if (cmcf->ports == NULL) {
        cmcf->ports = ngx_array_create(cf->temp_pool, 2,
                                       sizeof(ngx_http_conf_port_t));
        if (cmcf->ports == NULL) {
            return NGX_ERROR;
        }
    }

    sa = &lsopt->u.sockaddr;

    switch (sa->sa_family) {

#if (NGX_HAVE_INET6)
    case AF_INET6:
        sin6 = &lsopt->u.sockaddr_in6;
        p = sin6->sin6_port;
        break;
#endif

#if (NGX_HAVE_UNIX_DOMAIN)
    case AF_UNIX:
        p = 0;
        break;
#endif

    default: /* AF_INET */
        sin = &lsopt->u.sockaddr_in;
        p = sin->sin_port;
        break;
    }

    port = cmcf->ports->elts;
    for (i = 0; i < cmcf->ports->nelts; i++) {

        if (p != port[i].port || sa->sa_family != port[i].family) {
            continue;
        }

        /* a port is already in the port list */

        return ngx_http_add_addresses(cf, cscf, &port[i], lsopt);
    }

    /* add a port to the port list */

    port = ngx_array_push(cmcf->ports);
    if (port == NULL) {
        return NGX_ERROR;
    }

    port->family = sa->sa_family;
    port->port = p;
    port->addrs.elts = NULL;

    return ngx_http_add_address(cf, cscf, port, lsopt);
}