Beispiel #1
0
ngx_http_php_code_t *
ngx_http_php_code_from_string(ngx_pool_t *pool, ngx_str_t *code_str)
{
    ngx_http_php_code_t *code;
    size_t len;

    code = ngx_pcalloc(pool, sizeof(*code));
    if (code == NULL){
        return NGX_CONF_UNSET_PTR;
    }

    len = ngx_strlen(code_str->data);
    code->code.string = ngx_pcalloc(pool, len + 1);
    if (code->code.string == NULL){
        return NGX_CONF_UNSET_PTR;
    }
    ngx_cpystrn((u_char *)code->code.string, code_str->data, len + 1);
    code->code_type = NGX_HTTP_PHP_CODE_TYPE_STRING;

    //code->code_id.data = ngx_pnalloc(pool, sizeof("18446744073709551616")-1+NGX_TIME_T_LEN);
    //code->code_id.len = ngx_sprintf(code->code_id.data, "%ul%T", ngx_random(), ngx_time()) - code->code_id.data;

    code->code_id.len = 32;
    code->code_id.data = ngx_pnalloc(pool, 32);
    if (code->code_id.data == NULL) {
        return NGX_CONF_UNSET_PTR;
    }
    ngx_sprintf(code->code_id.data, "%08xD%08xD%08xD%08xD",
                (uint32_t) ngx_random(), (uint32_t) ngx_random(),
                (uint32_t) ngx_random(), (uint32_t) ngx_random());

    return code;
}
/**
 * Dada uma sequencia de opções de tamanho max_opcoes, gera uma string no buffer de tamanho
 * max_tam com caracteres aleatórios de opcoes.
 */
static void generate_random_string(ngx_str_t* buffer, const ngx_str_t* options) {
    
    u_int i;
    for (i=0; i<buffer->len; i++) {
        buffer->data[i] = options->data[ngx_random() % options->len];
    }
}
Beispiel #3
0
ngx_http_php_code_t *
ngx_http_php_code_from_file(ngx_pool_t *pool, ngx_str_t *code_file_path)
{
    ngx_http_php_code_t *code;
    size_t len;
    u_char *p;

    code = ngx_pcalloc(pool, sizeof(*code));
    if (code == NULL){
        return NGX_CONF_UNSET_PTR;
    }

    len = ngx_strlen((char *)code_file_path->data);
    if (len == 0){
        return NGX_CONF_UNSET_PTR;
    }else if (code_file_path->data[0] == '/' || code_file_path->data[0] == '$'){
        code->code.file = ngx_pcalloc(pool, len + 1);
        if (code->code.file == NULL){
            return NGX_CONF_UNSET_PTR;
        }
        ngx_cpystrn((u_char *)code->code.file, (u_char *)code_file_path->data, code_file_path->len + 1);    
    }else {
        code->code.file = ngx_pcalloc(pool, ngx_cycle->conf_prefix.len + len + 1);
        if (code->code.file == NULL){
            return NGX_CONF_UNSET_PTR;
        }
        p = ngx_cpystrn((u_char *)code->code.file, (u_char *)ngx_cycle->conf_prefix.data, ngx_cycle->conf_prefix.len + 1);
        ngx_cpystrn(p, (u_char *)code_file_path->data, code_file_path->len + 1);
    }
    code->code_type = NGX_HTTP_PHP_CODE_TYPE_FILE;

    //code->code_id.data = ngx_pnalloc(pool, sizeof("18446744073709551616")-1+NGX_TIME_T_LEN);
    //code->code_id.len = ngx_sprintf(code->code_id.data, "%ul%T", ngx_random(), ngx_time()) - code->code_id.data;

    code->code_id.len = 32;
    code->code_id.data = ngx_pnalloc(pool, 32);
    if (code->code_id.data == NULL) {
        return NGX_CONF_UNSET_PTR;
    }
    ngx_sprintf(code->code_id.data, "%08xD%08xD%08xD%08xD",
                (uint32_t) ngx_random(), (uint32_t) ngx_random(),
                (uint32_t) ngx_random(), (uint32_t) ngx_random());

    return code;
}
Beispiel #4
0
static void nchan_generate_random_boundary(u_char *buf, int sz) {
  //use the shitty-ass LFSR-based ngx_random. we're not looking for cryptographic randomness, 
  //just something unlikely
  static u_char   itoa64[] ="./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  int             i;
  u_char         *p = buf;
  
  for(i=0; i < sz; i++) {
    *p++ = itoa64[ngx_random() % 64];
  }
}
static ngx_int_t
ngx_http_requestid_set_variable(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
{
    ngx_md5_t                    md5;
    ngx_http_requestid_conf_t    *conf;
    u_char                       *end;
    u_char                       val[NGX_INT64_LEN * 3 + 3];
    u_char                       hashb[MD5_BHASH_LEN];
    ngx_uint_t                   i, k;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_requestid_module);

    if (conf->enable == 0) {
    	v->not_found = 1;
    	return NGX_OK;
    }

    end = ngx_sprintf(val, "%i,%ui,%i",
                      ngx_pid, r->connection->number, ngx_random());
    *end = 0;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "requestid: data for hash=%s", val);

    ngx_md5_init(&md5);
    ngx_md5_update(&md5, val, end-val);
    ngx_md5_final(hashb, &md5);

    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->len = MD5_HASH_LEN;
    v->data = ngx_pnalloc(r->pool, MD5_HASH_LEN);

    if (v->data == NULL) {
        return NGX_ERROR;
    }

    for (i = TIMESTAMP_LENGTH & ~1, k = 0; i < MD5_HASH_LEN; i += 2, ++k) {
        v->data[i]   = hex[hashb[k] >> 4];
        v->data[i+1] = hex[hashb[k] & 0xf];
    }

    ngx_snprintf(v->data, TIMESTAMP_LENGTH, "%ui%03d",
                 r->start_sec, r->start_msec);

    return NGX_OK;
}
static ngx_int_t
ngx_extra_var_uint(ngx_http_request_t *r,
    ngx_http_variable_value_t *v, uintptr_t data)
{
    ngx_uint_t  value;
    u_char     *p;

    p = ngx_pnalloc(r->pool, NGX_INT_T_LEN);
    if (p == NULL) {
        return NGX_ERROR;
    }

    switch (data) {
    case NGX_EXTRAVAR_REDIRECT_COUNT:
        value = NGX_HTTP_MAX_URI_CHANGES + 1 - r->uri_changes;
        break;

    case NGX_EXTRAVAR_SUBREQUEST_COUNT:
        value = NGX_HTTP_MAX_SUBREQUESTS + 1 - r->subrequests;
        break;

    case NGX_EXTRAVAR_PROCESS_SLOT:
        value = ngx_process_slot;
        break;

    case NGX_EXTRAVAR_CONNECTION_REQUESTS:
        value = r->connection->requests;
        break;

    case NGX_EXTRAVAR_RANDOM:
        value = ngx_random();
        break;

    default:
        v->not_found = 1;
        return NGX_OK;
    }

    v->len = ngx_sprintf(p, "%ui", value) - p;
    v->valid = 1;
    v->no_cacheable = 0;
    v->not_found = 0;
    v->data = p;

    return NGX_OK;
}
ngx_int_t
ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
    ngx_mail_core_srv_conf_t *cscf)
{
    s->salt.data = ngx_palloc(c->pool,
                              sizeof(" <18446744073709551616.@>" CRLF) - 1
                              + NGX_TIME_T_LEN
                              + cscf->server_name.len);
    if (s->salt.data == NULL) {
        return NGX_ERROR;
    }

    s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF,
                              ngx_random(), ngx_time(), &cscf->server_name)
                  - s->salt.data;

    return NGX_OK;
}
static char *ngx_http_upstream_dynamic_servers_merge_conf(ngx_conf_t *cf, void *parent, void *child) {
    // If any dynamic servers are present, verify that a "resolver" is setup as
    // the http level.
    ngx_http_upstream_dynamic_server_main_conf_t  *udsmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_dynamic_servers_module);

    if (udsmcf->dynamic_servers.nelts > 0) {
        ngx_http_core_loc_conf_t *core_loc_conf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
#if nginx_version >= 1009011
        if (core_loc_conf->resolver == NULL || core_loc_conf->resolver->connections.nelts == 0) {
#else
        if (core_loc_conf->resolver == NULL || core_loc_conf->resolver->udp_connections.nelts == 0) {
#endif
            ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "resolver must be defined at the 'http' level of the config");
            return NGX_CONF_ERROR;
        }
        udsmcf->conf_ctx = cf->ctx;
        udsmcf->resolver = core_loc_conf->resolver;
        ngx_conf_merge_msec_value(udsmcf->resolver_timeout, core_loc_conf->resolver_timeout, 30000);
    }

    return NGX_CONF_OK;
}

static ngx_int_t ngx_http_upstream_dynamic_servers_init_process(ngx_cycle_t *cycle) {
    ngx_http_upstream_dynamic_server_main_conf_t  *udsmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_upstream_dynamic_servers_module);
    ngx_http_upstream_dynamic_server_conf_t       *dynamic_server = udsmcf->dynamic_servers.elts;
    ngx_uint_t i;
    ngx_event_t *timer;
    ngx_uint_t refresh_in;

    for (i = 0; i < udsmcf->dynamic_servers.nelts; i++) {
        timer = &dynamic_server[i].timer;
        timer->handler = ngx_http_upstream_dynamic_server_resolve;
        timer->log = cycle->log;
        timer->data = &dynamic_server[i];

        refresh_in = ngx_random() % 1000;
        ngx_log_debug(NGX_LOG_DEBUG_CORE, cycle->log, 0, "upstream-dynamic-servers: Initial DNS refresh of '%V' in %ims", &dynamic_server[i].host, refresh_in);
        ngx_add_timer(timer, refresh_in);
    }

    return NGX_OK;
}
Beispiel #9
0
ngx_int_t
oc_smtp_salt(oc_smtp_session_t *s, ngx_connection_t *c,
			oc_smtp_core_srv_conf_t *cscf)
{
	s->salt.data = ngx_pnalloc(c->pool,
				sizeof(" <18446744073709551616.@>" CRLF) - 1
				+ NGX_TIME_T_LEN
				+ cscf->server_name.len);
	if (s->salt.data == NULL) {
		return NGX_ERROR;
	}

	//根据CRAM-MD5的协议规定,生成随机的验证串
	s->salt.len = ngx_sprintf(s->salt.data, "<%ul.%T@%V>" CRLF,
				ngx_random(), ngx_time(), &cscf->server_name)
		- s->salt.data;

	return NGX_OK;
}
static void
ngx_http_gettoken_connect(ngx_http_gettoken_connection_t *c)
{
    ngx_peer_connection_t *pconn;
    ngx_connection_t *conn;
    ngx_addr_t *addr;
    ngx_int_t rc;

    addr = &c->server->parsed_url.addrs[ngx_random() % c->server->parsed_url.naddrs];

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_gettoken: Connecting to LDAP server \"%V\".",
        &addr->name);

    pconn = &c->conn;
    pconn->sockaddr = addr->sockaddr;
    pconn->socklen = addr->socklen;
    pconn->name = &addr->name;
    pconn->get = ngx_event_get_peer;
    pconn->log = c->log;
    pconn->log_error = NGX_ERROR_ERR;

    rc = ngx_event_connect_peer(pconn);
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_gettoken: ngx_event_connect_peer() -> %d.", rc);
    if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
        ngx_log_error(NGX_LOG_ERR, c->log, 0, "http_gettoken: Unable to connect to LDAP server \"%V\".",
            &addr->name);
        ngx_add_timer(&c->reconnect_event, c->server->reconnect_timeout);
        return;
    }

    conn = pconn->connection;
    conn->data = c;

    conn->write->handler = ngx_http_gettoken_connect_handler;
    conn->read->handler = ngx_http_gettoken_read_handler;
    ngx_add_timer(conn->read, c->server->connect_timeout);
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_gettoken: connect_timeout=%d.", c->server->connect_timeout);


    c->state = STATE_CONNECTING;
}
static ngx_int_t ngx_http_healthcheck_procinit(ngx_cycle_t *cycle) {
    ngx_uint_t i;
    ngx_msec_t t;

    if (ngx_http_healthchecks_arr->nelts == 0) {
      return NGX_OK;
    }

     // Otherwise, the distribution isn't very random because each process
     // is a fork, so they all have the same seed
    srand(ngx_pid);
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cycle->log, 0,
            "healthcheck: Adding events to worker process %P", ngx_pid);
    for (i=0; i<ngx_http_healthchecks_arr->nelts; i++) {
        ngx_http_healthchecks[i].shm = &ngx_http_healthchecks_shm[i];

        if (ngx_http_healthchecks[i].conf->healthcheck_enabled) {

            ngx_http_healthchecks[i].ownership_ev.handler =
                ngx_http_healthcheck_try_for_ownership;
            ngx_http_healthchecks[i].ownership_ev.log = cycle->log;
            ngx_http_healthchecks[i].ownership_ev.data =
                &ngx_http_healthchecks[i];
            // I'm not sure why the timer_set needs to be reset to zero.
            // It shouldn't (??), but it does when you HUP the process
            ngx_http_healthchecks[i].ownership_ev.timer_set = 0;

            ngx_http_healthchecks[i].health_ev.handler =
                ngx_http_healthcheck_begin_healthcheck;
            ngx_http_healthchecks[i].health_ev.log = cycle->log;
            ngx_http_healthchecks[i].health_ev.data =
                &ngx_http_healthchecks[i];
            ngx_http_healthchecks[i].health_ev.timer_set = 0;

            t = abs(ngx_random() % ngx_http_healthchecks[i].conf->health_delay);
            ngx_add_timer(&ngx_http_healthchecks[i].ownership_ev, t);
        }
    }
    return NGX_OK;
}
Beispiel #12
0
static void
ngx_zeromq_randomized_endpoint_regen(ngx_str_t *addr)
{
    in_port_t   port;
    u_char     *p;

    p = addr->data + addr->len;

    while (p > addr->data) {
        if (*p == ':') {
            break;
        }

        p--;
    }

    port = 1024 + ngx_pid + ngx_random();

    addr->len = ngx_snprintf(p + 1, sizeof("65535") - 1, "%d", port)
                - addr->data;
    addr->data[addr->len] = '\0';
}
static int
ngx_http_kafka_lua_log(lua_State *L)
{
    ngx_kfk_ctx_t			*kfk = ngx_kfk;
    ngx_http_request_t      *r;
    ngx_http_kafka_ctx_t	*ctx;
    ngx_kfk_topic_t			*topic;
    ngx_kfk_toppar_t		*toppar;
    ngx_uint_t				 partition;
    u_char              	*p;
    size_t               	 len;
    int                  	 n, type;

    n = lua_gettop(L);
    if (n < 3) {
        return luaL_error(L, "kfk.log: expecting at least 3 arguments but got %d", n);
    }

    if (kfk == NULL) {
    	lua_pushnil(L);
    	lua_pushliteral(L, "kafka not start");
    	return 2;
    }

	if (kfk->pending_msgs_cnt + 1 > kfk->cf->buffering_max_msg) {
    	lua_pushnil(L);
    	lua_pushliteral(L, "buffering queue is full, try later");
		return 2;
	}

    p = (u_char *) luaL_checklstring(L, 1, &len);
    if (len == 0) {
    	lua_pushnil(L);
    	lua_pushliteral(L, "unknown topic");
    	return 2;
    }

    topic = ngx_http_kafka_topic_find(kfk, p, len);
    if (topic == NULL || topic->state == NGX_KFK_TOPIC_UNKNOWN) {
        lua_pushnil(L);
        lua_pushliteral(L, "unknown topic");
        return 2;
    }

    if (topic->toppars == NULL || topic->toppars->nelts == 0) {
    	lua_pushnil(L);
        lua_pushliteral(L, "unknown topic(partition uninitilized)");
    	return 2;
    }

    type = lua_type(L, 2);

    switch (type) {
    	case LUA_TNIL:
    		partition = (ngx_uint_t)ngx_random() % topic->toppars->nelts;
    		break;

    	case LUA_TSTRING:
    		p = (u_char *) lua_tolstring(L, 2, &len);
    		partition = ngx_http_kafka_partition(p, len, topic->toppars->nelts);
    		break;

    	default:
            return luaL_argerror(L, 2, "expect string or nil");
    }

    toppar = ngx_http_kafka_toppar_get_valid(topic, partition);
    if (toppar == NULL) {
    	lua_pushnil(L);
        lua_pushliteral(L, "broker not available");
        return 2;
    }

    r = ngx_http_lua_get_request(L);
    ctx = ngx_http_get_module_ctx(r, ngx_http_kafka_module);

    if (ctx == NULL) {
    	ctx = ngx_palloc(r->pool, sizeof(ngx_http_kafka_ctx_t));

    	if (ctx == NULL) {
    		lua_pushnil(L);
    		lua_pushliteral(L, "no enough memory");
    		return 2;
    	}

    	ctx->topic = topic;
    	ctx->toppar = toppar;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_kafka_module);

    return ngx_http_kafka_lua_push(L);
}
ngx_int_t
ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
    ngx_http_upstream_resolved_t *ur)
{
    u_char                            *p;
    size_t                             len;
    ngx_uint_t                         i, n;
    struct sockaddr_in                *sin;
    ngx_http_upstream_rr_peers_t      *peers;
    ngx_http_upstream_rr_peer_data_t  *rrp;

    rrp = r->upstream->peer.data;

    if (rrp == NULL) {
        rrp = ngx_palloc(r->pool, sizeof(ngx_http_upstream_rr_peer_data_t));
        if (rrp == NULL) {
            return NGX_ERROR;
        }

        r->upstream->peer.data = rrp;
    }

    peers = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_rr_peers_t)
                     + sizeof(ngx_http_upstream_rr_peer_t) * (ur->naddrs - 1));
    if (peers == NULL) {
        return NGX_ERROR;
    }

    peers->single = (ur->naddrs == 1);
    peers->number = ur->naddrs;
    peers->init_number = ngx_random() % peers->number;
    peers->name = &ur->host;

    if (ur->sockaddr) {
        peers->peer[0].sockaddr = ur->sockaddr;
        peers->peer[0].socklen = ur->socklen;
        peers->peer[0].name = ur->host;
        peers->peer[0].id.len = 0;
        peers->peer[0].id.data = NULL;
        peers->peer[0].weight = 1;
        peers->peer[0].effective_weight = 1;
        peers->peer[0].current_weight = 0;
        peers->peer[0].max_fails = 1;
        peers->peer[0].fail_timeout = 10;
#if (NGX_HTTP_UPSTREAM_CHECK)
        peers->peer[0].check_index = (ngx_uint_t) NGX_ERROR;
#endif

    } else {

        for (i = 0; i < ur->naddrs; i++) {

            len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;

            p = ngx_pnalloc(r->pool, len);
            if (p == NULL) {
                return NGX_ERROR;
            }

            len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
            len = ngx_sprintf(&p[len], ":%d", ur->port) - p;

            sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
            if (sin == NULL) {
                return NGX_ERROR;
            }

            sin->sin_family = AF_INET;
            sin->sin_port = htons(ur->port);
            sin->sin_addr.s_addr = ur->addrs[i];

            peers->peer[i].sockaddr = (struct sockaddr *) sin;
            peers->peer[i].socklen = sizeof(struct sockaddr_in);
            peers->peer[i].name.len = len;
            peers->peer[i].name.data = p;
            peers->peer[i].id.len = 0;
            peers->peer[i].id.data = NULL;
            peers->peer[i].weight = 1;
            peers->peer[i].effective_weight = 1;
            peers->peer[i].current_weight = 0;
            peers->peer[i].max_fails = 1;
            peers->peer[i].fail_timeout = 10;
#if (NGX_HTTP_UPSTREAM_CHECK)
            peers->peer[i].check_index = (ngx_uint_t) NGX_ERROR;
#endif
        }
    }

    rrp->peers = peers;
    rrp->current = 0;

    if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
        rrp->tried = &rrp->data;
        rrp->data = 0;

    } else {
        n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
                / (8 * sizeof(uintptr_t));

        rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
        if (rrp->tried == NULL) {
            return NGX_ERROR;
        }
    }

    r->upstream->peer.get = ngx_http_upstream_get_round_robin_peer;
    r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
    r->upstream->peer.tries = rrp->peers->number;
#if (NGX_HTTP_SSL)
    r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
    r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
#endif

    return NGX_OK;
}
static void
ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
{
    ngx_http_request_t                  *r;
    ngx_connection_t                    *c;
    ngx_http_upstream_resolved_t        *ur;
    ngx_http_lua_ctx_t                  *lctx;
    lua_State                           *L;
    ngx_http_lua_socket_udp_upstream_t  *u;
    u_char                              *p;
    size_t                               len;
    struct sockaddr_in                  *sin;
    ngx_uint_t                           i;
    unsigned                             waiting;

    u = ctx->data;
    r = u->request;
    c = r->connection;
    ur = u->resolved;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "lua udp socket resolve handler");

    lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (lctx == NULL) {
        return;
    }

    lctx->cur_co_ctx = u->co_ctx;

    u->co_ctx->cleanup = NULL;

    L = lctx->cur_co_ctx->co;

    dd("setting socket_ready to 1");

    waiting = u->waiting;

    if (ctx->state) {
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "lua udp socket resolver error: %s (waiting: %d)",
                       ngx_resolver_strerror(ctx->state), (int) u->waiting);

        lua_pushnil(L);
        lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len);
        lua_pushfstring(L, " could not be resolved (%d: %s)",
                        (int) ctx->state,
                        ngx_resolver_strerror(ctx->state));
        lua_concat(L, 2);

        u->prepare_retvals = ngx_http_lua_socket_error_retval_handler;
        ngx_http_lua_socket_udp_handle_error(r, u,
                                             NGX_HTTP_LUA_SOCKET_FT_RESOLVER);

        if (waiting) {
            ngx_http_run_posted_requests(c);
        }

        return;
    }

    ur->naddrs = ctx->naddrs;
    ur->addrs = ctx->addrs;

#if (NGX_DEBUG)
    {
    in_addr_t   addr;
    ngx_uint_t  i;

    for (i = 0; i < ctx->naddrs; i++) {
        dd("addr i: %d %p", (int) i,  &ctx->addrs[i]);

        addr = ntohl(ctx->addrs[i]);

        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "name was resolved to %ud.%ud.%ud.%ud",
                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,
                       (addr >> 8) & 0xff, addr & 0xff);
    }
    }
#endif

    if (ur->naddrs == 0) {
        ngx_resolve_name_done(ctx);
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;

        lua_pushnil(L);
        lua_pushliteral(L, "name cannot be resolved to a address");

        if (waiting) {
            ngx_http_run_posted_requests(c);
        }

        return;
    }

    if (ur->naddrs == 1) {
        i = 0;

    } else {
        i = ngx_random() % ur->naddrs;
    }

    dd("selected addr index: %d", (int) i);

    len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;

    p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in));
    if (p == NULL) {
        ngx_resolve_name_done(ctx);
        u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER;

        lua_pushnil(L);
        lua_pushliteral(L, "out of memory");

        if (waiting) {
            ngx_http_run_posted_requests(c);
        }

        return;
    }

    sin = (struct sockaddr_in *) &p[len];
    ngx_memzero(sin, sizeof(struct sockaddr_in));

    len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
    len = ngx_sprintf(&p[len], ":%d", ur->port) - p;

    sin->sin_family = AF_INET;
    sin->sin_port = htons(ur->port);
    sin->sin_addr.s_addr = ur->addrs[i];

    ur->sockaddr = (struct sockaddr *) sin;
    ur->socklen = sizeof(struct sockaddr_in);

    ur->host.data = p;
    ur->host.len = len;
    ur->naddrs = 1;

    ur->ctx = NULL;

    ngx_resolve_name_done(ctx);

    u->waiting = 0;

    if (waiting) {
        lctx->resume_handler = ngx_http_lua_socket_udp_resume;
        r->write_event_handler(r);
        ngx_http_run_posted_requests(c);

    } else {
        (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L);
    }
}
static void
ngx_http_lua_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
{
    ngx_http_request_t                  *r;
    ngx_connection_t                    *c;
    ngx_http_upstream_resolved_t        *ur;
    ngx_http_lua_ctx_t                  *lctx;
    lua_State                           *L;
    ngx_http_lua_socket_udp_upstream_t  *u;
    u_char                              *p;
    size_t                               len;
#if defined(nginx_version) && nginx_version >= 1005008
    socklen_t                            socklen;
    struct sockaddr                     *sockaddr;
#else
    struct sockaddr_in                  *sin;
#endif
    ngx_uint_t                           i;
    unsigned                             waiting;

    u = ctx->data;
    r = u->request;
    c = r->connection;
    ur = u->resolved;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                   "lua udp socket resolve handler");

    lctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
    if (lctx == NULL) {
        return;
    }

    lctx->cur_co_ctx = u->co_ctx;

    u->co_ctx->cleanup = NULL;

    L = lctx->cur_co_ctx->co;

    dd("setting socket_ready to 1");

    waiting = u->waiting;

    if (ctx->state) {
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "lua udp socket resolver error: %s (waiting: %d)",
                       ngx_resolver_strerror(ctx->state), (int) u->waiting);

        lua_pushnil(L);
        lua_pushlstring(L, (char *) ctx->name.data, ctx->name.len);
        lua_pushfstring(L, " could not be resolved (%d: %s)",
                        (int) ctx->state,
                        ngx_resolver_strerror(ctx->state));
        lua_concat(L, 2);

#if 1
        ngx_resolve_name_done(ctx);
        ur->ctx = NULL;
#endif

        u->prepare_retvals = ngx_http_lua_socket_error_retval_handler;
        ngx_http_lua_socket_udp_handle_error(r, u,
                                             NGX_HTTP_LUA_SOCKET_FT_RESOLVER);

        if (waiting) {
            ngx_http_run_posted_requests(c);
        }

        return;
    }

    ur->naddrs = ctx->naddrs;
    ur->addrs = ctx->addrs;

#if (NGX_DEBUG)
    {
#   if defined(nginx_version) && nginx_version >= 1005008
    u_char      text[NGX_SOCKADDR_STRLEN];
    ngx_str_t   addr;
#   else
    in_addr_t   addr;
#   endif
    ngx_uint_t  i;

#   if defined(nginx_version) && nginx_version >= 1005008
    addr.data = text;

    for (i = 0; i < ctx->naddrs; i++) {
        addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
                                 text, NGX_SOCKADDR_STRLEN, 0);

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "name was resolved to %V", &addr);
    }
#   else
    for (i = 0; i < ctx->naddrs; i++) {
        dd("addr i: %d %p", (int) i,  &ctx->addrs[i]);

        addr = ntohl(ctx->addrs[i]);

        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
                       "name was resolved to %ud.%ud.%ud.%ud",
                       (addr >> 24) & 0xff, (addr >> 16) & 0xff,
                       (addr >> 8) & 0xff, addr & 0xff);
    }
#   endif
    }
#endif

    ngx_http_lua_assert(ur->naddrs > 0);

    if (ur->naddrs == 1) {
        i = 0;

    } else {
        i = ngx_random() % ur->naddrs;
    }

    dd("selected addr index: %d", (int) i);

#if defined(nginx_version) && nginx_version >= 1005008
    socklen = ur->addrs[i].socklen;

    sockaddr = ngx_palloc(r->pool, socklen);
    if (sockaddr == NULL) {
        goto nomem;
    }

    ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen);

    switch (sockaddr->sa_family) {
#if (NGX_HAVE_INET6)
    case AF_INET6:
        ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port);
        break;
#endif
    default: /* AF_INET */
        ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port);
    }

    p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
    if (p == NULL) {
        goto nomem;
    }

    len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
    ur->sockaddr = sockaddr;
    ur->socklen = socklen;

#else
    /* for nginx older than 1.5.8 */

    len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;

    p = ngx_pnalloc(r->pool, len + sizeof(struct sockaddr_in));
    if (p == NULL) {
        goto nomem;
    }

    sin = (struct sockaddr_in *) &p[len];
    ngx_memzero(sin, sizeof(struct sockaddr_in));

    len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
    len = ngx_sprintf(&p[len], ":%d", ur->port) - p;

    sin->sin_family = AF_INET;
    sin->sin_port = htons(ur->port);
    sin->sin_addr.s_addr = ur->addrs[i];

    ur->sockaddr = (struct sockaddr *) sin;
    ur->socklen = sizeof(struct sockaddr_in);
#endif

    ur->host.data = p;
    ur->host.len = len;
    ur->naddrs = 1;

    ngx_resolve_name_done(ctx);
    ur->ctx = NULL;

    u->waiting = 0;

    if (waiting) {
        lctx->resume_handler = ngx_http_lua_socket_udp_resume;
        r->write_event_handler(r);
        ngx_http_run_posted_requests(c);

    } else {
        (void) ngx_http_lua_socket_resolve_retval_handler(r, u, L);
    }

    return;

nomem:

    if (ur->ctx) {
        ngx_resolve_name_done(ctx);
        ur->ctx = NULL;
    }

    u->prepare_retvals = ngx_http_lua_socket_error_retval_handler;
    ngx_http_lua_socket_udp_handle_error(r, u,
                                         NGX_HTTP_LUA_SOCKET_FT_NOMEM);

    if (waiting) {
        ngx_http_run_posted_requests(c);

    } else {
        lua_pushnil(L);
        lua_pushliteral(L, "no memory");
    }
}
Beispiel #17
0
ngx_int_t
ngx_http_statsd_handler(ngx_http_request_t *r)
{
    u_char                    line[STATSD_MAX_STR], *p;
    const char *              metric_type;
    ngx_http_statsd_conf_t   *ulcf;
	ngx_statsd_stat_t 		 *stats;
	ngx_statsd_stat_t		  stat;
	ngx_uint_t 			      c;
	ngx_uint_t				  n;
	ngx_str_t				  s;
	ngx_flag_t				  b;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http statsd handler");

    ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module);

    if (ulcf->off == 1 || ulcf->endpoint == NULL) {
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off");
        return NGX_OK;
    }

	// Use a random distribution to sample at sample rate.
	if (ulcf->sample_rate < 100 && (uint) (ngx_random() % 100) >= ulcf->sample_rate) {
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample");
		return NGX_OK;
	}

	stats = ulcf->stats->elts;
	for (c = 0; c < ulcf->stats->nelts; c++) {

		stat = stats[c];
		s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key);
		ngx_escape_statsd_key(s.data, s.data, s.len);

		n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric);
		b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid);

		if (b == 0 || s.len == 0 || n <= 0) {
			// Do not log if not valid, key is invalid, or valud is lte 0. 
			ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send");
         	continue;
		};

		if (stat.type == STATSD_TYPE_COUNTER) {
			metric_type = "c";
		} else if (stat.type == STATSD_TYPE_TIMING) {
			metric_type = "ms";
		} else {
			metric_type = NULL;
		}

		if (metric_type) {
			if (ulcf->sample_rate < 100) {
				p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%d|%s|@0.%02d", &s, n, metric_type, ulcf->sample_rate);
			} else {
				p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%d|%s", &s, n, metric_type);
			}
			ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line);
		}
	}

    return NGX_OK;
}
static void 
ngx_http_php_socket_resolve_handler(ngx_resolver_ctx_t *ctx)
{
    ngx_http_request_t              *r;
    //ngx_connection_t                *c;
    ngx_http_upstream_resolved_t    *ur;
    ngx_http_php_socket_upstream_t  *u;
    u_char                          *p;
    size_t                          len;
    //ngx_http_php_ctx_t              *php_ctx;

    socklen_t                        socklen;
    struct sockaddr                 *sockaddr;

    ngx_uint_t                      i;

    u = ctx->data;
    r = u->request;
    //c = r->connection;
    ur = u->resolved;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "php socket resolve handler");

    ngx_php_debug("php socket resolve handler");

    if (ctx->state) {
        return ;
    }

    ur->naddrs = ctx->naddrs;
    ur->addrs = ctx->addrs;

#if (NGX_DEBUG)
    {
    u_char      text[NGX_SOCKADDR_STRLEN];
    ngx_str_t   addr;
    ngx_uint_t  i;

    addr.data = text;

    for (i = 0; i < ctx->naddrs; i++ ) {
        addr.len = ngx_sock_ntop(ur->addrs[i].sockaddr, ur->addrs[i].socklen,
                                 text, NGX_SOCKADDR_STRLEN, 0);

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                       "name was resolved to %V", &addr);
    }
    }
#endif

    if (ur->naddrs == 1) {
        i = 0;
    }else {
        i = ngx_random() % ur->naddrs;
    }

    socklen = ur->addrs[i].socklen;

    sockaddr = ngx_palloc(r->pool, socklen);
    if (sockaddr == NULL) {

    }

    ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen);

    switch (sockaddr->sa_family) {
#if (NGX_HAVE_INET6)
    case AF_INET6:
        ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port);
        break;
#endif
    default: /* AF_INET */
        ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port);
    }

    p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN);
    if (p == NULL) {
        return ;
    }

    len = ngx_sock_ntop(sockaddr, socklen, p, NGX_SOCKADDR_STRLEN, 1);
    ur->sockaddr = sockaddr;
    ur->socklen = socklen;

    ur->host.data = p;
    ur->host.len = len;
    ur->naddrs = 1;

    ngx_resolve_name_done(ctx);
    ur->ctx = NULL;

    ngx_http_php_socket_resolve_retval_handler(r, u);

    return ;
}
static ngx_int_t
ngx_http_random_index_handler(ngx_http_request_t *r)
{
    u_char                            *last, *filename;
    size_t                             len, allocated, root;
    ngx_err_t                          err;
    ngx_int_t                          rc;
    ngx_str_t                          path, uri, *name;
    ngx_dir_t                          dir;
    ngx_uint_t                         n, level;
    ngx_array_t                        names;
    ngx_http_random_index_loc_conf_t  *rlcf;

    if (r->uri.data[r->uri.len - 1] != '/') {
        return NGX_DECLINED;
    }

    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
        return NGX_DECLINED;
    }

    rlcf = ngx_http_get_module_loc_conf(r, ngx_http_random_index_module);

    if (!rlcf->enable) {
        return NGX_DECLINED;
    }

#if (NGX_HAVE_D_TYPE)
    len = NGX_DIR_MASK_LEN;
#else
    len = NGX_HTTP_RANDOM_INDEX_PREALLOCATE;
#endif

    last = ngx_http_map_uri_to_path(r, &path, &root, len);
    if (last == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    allocated = path.len;

    path.len = last - path.data - 1;
    path.data[path.len] = '\0';

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http random index: \"%s\"", path.data);

    if (ngx_open_dir(&path, &dir) == NGX_ERROR) {
        err = ngx_errno;

        if (err == NGX_ENOENT
            || err == NGX_ENOTDIR
            || err == NGX_ENAMETOOLONG)
        {
            level = NGX_LOG_ERR;
            rc = NGX_HTTP_NOT_FOUND;

        } else if (err == NGX_EACCES) {
            level = NGX_LOG_ERR;
            rc = NGX_HTTP_FORBIDDEN;

        } else {
            level = NGX_LOG_CRIT;
            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_log_error(level, r->connection->log, err,
                      ngx_open_dir_n " \"%s\" failed", path.data);

        return rc;
    }

    if (ngx_array_init(&names, r->pool, 32, sizeof(ngx_str_t)) != NGX_OK) {
        return ngx_http_random_index_error(r, &dir, &path);
    }

    filename = path.data;
    filename[path.len] = '/';

    for ( ;; ) {
        ngx_set_errno(0);

        if (ngx_read_dir(&dir) == NGX_ERROR) {
            err = ngx_errno;

            if (err != NGX_ENOMOREFILES) {
                ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
                              ngx_read_dir_n " \"%V\" failed", &path);
                return ngx_http_random_index_error(r, &dir, &path);
            }

            break;
        }

        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "http random index file: \"%s\"", ngx_de_name(&dir));

        if (ngx_de_name(&dir)[0] == '.') {
            continue;
        }

        len = ngx_de_namelen(&dir);

        if (dir.type == 0 || ngx_de_is_link(&dir)) {

            /* 1 byte for '/' and 1 byte for terminating '\0' */

            if (path.len + 1 + len + 1 > allocated) {
                allocated = path.len + 1 + len + 1
                                     + NGX_HTTP_RANDOM_INDEX_PREALLOCATE;

                filename = ngx_pnalloc(r->pool, allocated);
                if (filename == NULL) {
                    return ngx_http_random_index_error(r, &dir, &path);
                }

                last = ngx_cpystrn(filename, path.data, path.len + 1);
                *last++ = '/';
            }

            ngx_cpystrn(last, ngx_de_name(&dir), len + 1);

            if (ngx_de_info(filename, &dir) == NGX_FILE_ERROR) {
                err = ngx_errno;

                if (err != NGX_ENOENT) {
                    ngx_log_error(NGX_LOG_CRIT, r->connection->log, err,
                                  ngx_de_info_n " \"%s\" failed", filename);
                    return ngx_http_random_index_error(r, &dir, &path);
                }

                if (ngx_de_link_info(filename, &dir) == NGX_FILE_ERROR) {
                    ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                                  ngx_de_link_info_n " \"%s\" failed",
                                  filename);
                    return ngx_http_random_index_error(r, &dir, &path);
                }
            }
        }

        if (!ngx_de_is_file(&dir)) {
            continue;
        }

        name = ngx_array_push(&names);
        if (name == NULL) {
            return ngx_http_random_index_error(r, &dir, &path);
        }

        name->len = len;

        name->data = ngx_pnalloc(r->pool, len);
        if (name->data == NULL) {
            return ngx_http_random_index_error(r, &dir, &path);
        }

        ngx_memcpy(name->data, ngx_de_name(&dir), len);
    }

    if (ngx_close_dir(&dir) == NGX_ERROR) {
        ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno,
                      ngx_close_dir_n " \"%s\" failed", &path);
    }

    n = names.nelts;

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

    name = names.elts;

    n = (ngx_uint_t) (((uint64_t) ngx_random() * n) / 0x80000000);

    uri.len = r->uri.len + name[n].len;

    uri.data = ngx_pnalloc(r->pool, uri.len);
    if (uri.data == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    last = ngx_copy(uri.data, r->uri.data, r->uri.len);
    ngx_memcpy(last, name[n].data, name[n].len);

    return ngx_http_internal_redirect(r, &uri, &r->args);
}
static ngx_int_t 
ngx_tcp_check_init_process(ngx_cycle_t *cycle) 
{
    ngx_str_t                      shm_name;
    ngx_uint_t                     i;
    ngx_msec_t                     t, delay;
    check_conf_t                  *cf;
    ngx_shm_zone_t                *shm_zone;
    ngx_tcp_check_peer_shm_t      *peer_shm;
    ngx_tcp_check_peers_shm_t     *peers_shm;
    ngx_tcp_check_peer_conf_t     *peer_conf;
    ngx_tcp_check_peers_conf_t    *peers_conf;
    ngx_tcp_upstream_srv_conf_t   *uscf;

    if (ngx_tcp_check_get_shm_name(&shm_name, cycle->pool) == NGX_ERROR) {
        return NGX_ERROR;
    }

    shm_zone = ngx_shared_memory_find(cycle, &shm_name, &ngx_tcp_upstream_module);

    if (shm_zone == NULL || shm_zone->data == NULL) {
        return NGX_OK;
    }

    peers_conf = shm_zone->data;
    peers_shm = peers_conf->peers_shm;

    ngx_log_debug2(NGX_LOG_DEBUG_TCP, cycle->log, 0, 
            "tcp check upstream init_process, shm_name: %V, peer number: %ud",
            &shm_name, peers_conf->peers.nelts);

    srand(ngx_pid);

    peer_conf = peers_conf->peers.elts;
    peer_shm = peers_shm->peers;

    for (i = 0; i < peers_conf->peers.nelts; i++) {
        peer_conf[i].shm = &peer_shm[i];

        peer_conf[i].check_ev.handler = ngx_tcp_check_begin_handler;
        peer_conf[i].check_ev.log = cycle->log;
        peer_conf[i].check_ev.data = &peer_conf[i];
        peer_conf[i].check_ev.timer_set = 0;

        peer_conf[i].check_timeout_ev.handler = ngx_tcp_check_timeout_handler;
        peer_conf[i].check_timeout_ev.log = cycle->log;
        peer_conf[i].check_timeout_ev.data = &peer_conf[i];
        peer_conf[i].check_timeout_ev.timer_set = 0;

        uscf = peer_conf[i].conf;
        cf = uscf->check_type_conf;

        if (cf->need_pool) {
            peer_conf[i].pool = ngx_create_pool(ngx_pagesize, cycle->log);
            if (peer_conf[i].pool == NULL) {
                return NGX_ERROR;
            }
        }

        peer_conf[i].send_handler = cf->send_handler;
        peer_conf[i].recv_handler = cf->recv_handler;

        peer_conf[i].init = cf->init;
        peer_conf[i].parse = cf->parse;
        peer_conf[i].reinit = cf->reinit;

        /* Default delay interval is 1 second. 
           I don't want to trigger the check event too close. */
        delay = uscf->check_interval > 1000 ? uscf->check_interval : 1000;
        t = ngx_random() % delay;

        ngx_add_timer(&peer_conf[i].check_ev, t);
    }

    return NGX_OK;
}
ngx_int_t
ngx_http_check_add_timers(ngx_cycle_t *cycle)
{
    ngx_uint_t                          i;
    ngx_msec_t                          t, delay;
    check_conf_t                       *cf;
    ngx_http_check_peer_t              *peer;
    ngx_http_check_peers_t             *peers;
    ngx_http_check_peer_shm_t          *peer_shm;
    ngx_http_check_peers_shm_t         *peers_shm;
    ngx_http_upstream_check_srv_conf_t *ucscf;

    peers = check_peers_ctx;
    if (peers == NULL) {
        return NGX_OK;
    }

    peers_shm = peers->peers_shm;
    if (peers_shm == NULL) {
        return NGX_OK;
    }

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, cycle->log, 0,
                   "http check upstream init_process, shm_name: %V, "
                   "peer number: %ud",
                   &peers->check_shm_name,
                   peers->peers.nelts);

    srandom(ngx_pid);

    peer = peers->peers.elts;
    peer_shm = peers_shm->peers;

    for (i = 0; i < peers->peers.nelts; i++) {
        peer[i].shm = &peer_shm[i];

        peer[i].check_ev.handler = ngx_http_check_begin_handler;
        peer[i].check_ev.log = cycle->log;
        peer[i].check_ev.data = &peer[i];
        peer[i].check_ev.timer_set = 0;

        peer[i].check_timeout_ev.handler = ngx_http_check_timeout_handler;
        peer[i].check_timeout_ev.log = cycle->log;
        peer[i].check_timeout_ev.data = &peer[i];
        peer[i].check_timeout_ev.timer_set = 0;

        ucscf = peer[i].conf;
        cf = ucscf->check_type_conf;

        if (cf->need_pool) {
            peer[i].pool = ngx_create_pool(ngx_pagesize, cycle->log);
            if (peer[i].pool == NULL) {
                return NGX_ERROR;
            }
        }

        peer[i].send_handler = cf->send_handler;
        peer[i].recv_handler = cf->recv_handler;

        peer[i].init = cf->init;
        peer[i].parse = cf->parse;
        peer[i].reinit = cf->reinit;

        /*
         * I added a random start time. I don't want to trigger the check
         * event too close at the beginning.
         * */
        delay = ucscf->check_interval > 1000 ? ucscf->check_interval : 1000;
        t = ngx_random() % delay;

        ngx_add_timer(&peer[i].check_ev, t);
    }

    return NGX_OK;
}
static ngx_int_t ngx_http_statsd_handler(ngx_http_request_t *r) {
    u_char startline[STATSD_MAX_STR], *p, *line;
    size_t togo;
    const char *metric_type;
    ngx_http_statsd_conf_t *ulcf;
    ngx_statsd_stat_t *stats;
    ngx_statsd_stat_t stat;
    ngx_uint_t c;
    ngx_uint_t n;
    ngx_str_t set;
    ngx_str_t s;
    ngx_flag_t b;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http statsd handler");

    ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module);

    if (ulcf->off == 1 || ulcf->endpoint == NULL) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off");
        return NGX_OK;
    }

    // Use a random distribution to sample at sample rate.
    if (ulcf->sample_rate < 100 && (uint)(ngx_random() % 100) >= ulcf->sample_rate) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample");
        return NGX_OK;
    }

    stats = ulcf->stats->elts;
    line = startline;
    togo = STATSD_MAX_STR;
    for (c = 0; c < ulcf->stats->nelts; c++) {

        stat = stats[c];
        s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key);
        ngx_escape_statsd_key(s.data, s.data, s.len);

        n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric);
        b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid);
        set = ngx_http_statsd_set_get_value(r, stat.cmetric_str, stat.metric_str);

        if (b == 0 || s.len == 0 || (n <= 0 && set.len == 0)) {
            // Do not log if not valid, key is invalid, or value is less than 0.
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send");
            continue;
        };


        if (stat.type == STATSD_TYPE_COUNTER) {
            metric_type = "c";
        } else if (stat.type == STATSD_TYPE_TIMING) {
            metric_type = "ms";
        } else if (stat.type == STATSD_TYPE_SET) {
            metric_type = "s";
        } else {
            metric_type = NULL;
        }

        if (metric_type) {
            if (stat.type == STATSD_TYPE_SET) {
                // handle a set
                if (ulcf->sample_rate < 100) {
                    p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%V|s|@0.%02d", &s, &set, ulcf->sample_rate);
                } else {
                    p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%V|s", &s, &set);
                }
                ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line);
            } else {
                if (ulcf->sample_rate < 100) {
                    p = ngx_snprintf(line, togo, "%V:%d|%s|@0.%02d\n", &s, n, metric_type, ulcf->sample_rate);
                } else {
                    p = ngx_snprintf(line, togo, "%V:%d|%s\n", &s, n, metric_type);
                }
                if (p - line >= togo) {
                    if (line != startline) {
                        ngx_http_statsd_udp_send(ulcf->endpoint, startline, line - startline - sizeof(char));
                        c--;
                    }
                    line = startline;
                    togo = STATSD_MAX_STR;
                } else {
                    togo -= p - line;
                    line = p;
                }
            }
        }
        if (togo < STATSD_MAX_STR) {
            ngx_http_statsd_udp_send(ulcf->endpoint, startline, line - startline - sizeof(char));
        }
    }

    return NGX_OK;
}
ngx_int_t
ngx_http_statsd_handler(ngx_http_request_t *r)
{
    u_char                   *line, *p;
	uint					  line_len;
    size_t                    len;
    ngx_http_statsd_conf_t   *ulcf;
	ngx_statsd_stat_t 		 *stats;
	ngx_statsd_stat_t		  stat;
	ngx_uint_t 			      c;
	ngx_uint_t				  n;
	ngx_str_t				  s;
	ngx_flag_t				  b;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http statsd handler");

    ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module);

    if (ulcf->off == 1 || ulcf->endpoint == NULL) {
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off");
        return NGX_OK;
    }

	// Use a random distribution to sample at sample rate.
	if (ulcf->sample_rate < 100 && (uint) (ngx_random() % 100) >= ulcf->sample_rate) {
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample");
		return NGX_OK;
	}

	line_len = 100;
#if defined nginx_version && nginx_version >= 7003
	line = ngx_pnalloc(r->pool, line_len);
#else
	line = ngx_palloc(r->pool, line_len);
#endif
	if (line == NULL) {
		return NGX_ERROR;
	}

	stats = ulcf->stats->elts;
	for (c = 0; c < ulcf->stats->nelts; c++) {

		stat = stats[c];
		s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key);
		ngx_escape_statsd_key(s.data, s.data, s.len);

		n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric);
		b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid);

		if (b == 0 || s.len == 0 || n <= 0) {
			// Do not log if not valid, key is invalid, or valud is lte 0. 
			ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send");
         	continue;
		};

		len = s.len;
		len += sizeof(":") - 1;
		len += NGX_INT_T_LEN;
		len += sizeof("|c|@0.00") - 1;

		if (line_len < len) {
        	// Redimension buffer.
			line_len = len;
#if defined nginx_version && nginx_version >= 7003
			line = ngx_pnalloc(r->pool, line_len);
#else
			line = ngx_palloc(r->pool, line_len);
#endif
			if (line == NULL) {
				return NGX_ERROR;
			};
		};

		if (stat.type == STATSD_TYPE_COUNTER) {
			if (ulcf->sample_rate < 100) {
				p = ngx_sprintf(line, "%V:%d|c|@0.%02d", &s, n, ulcf->sample_rate);
			} else {
				p = ngx_sprintf(line, "%V:%d|c", &s, n);
			}
			ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line);
		} else if (stat.type == STATSD_TYPE_TIMING) {
			p = ngx_sprintf(line, "%V:%d|ms", &s, n);
			ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line);
		}
	}

    return NGX_OK;
}
ngx_int_t ngx_http_cp_header_handler(ngx_http_request_t *r)
{
    ngx_table_elt_t              *h;
    ngx_list_part_t              *part;
    ngx_http_upstream_t          *u;
    ngx_uint_t                   i, j, cmp_len;
    u_char                       *start, *end, *p;
    ngx_str_t                    cookie, cookie_name;
    ngx_str_t                    neteye_cookie;
    ngx_http_cp_loc_conf_t       *cplcf;
    ngx_uint_t                   magic;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 
            0, "cookie poison header handler");
    
    if (ngx_http_session_test_bypass(r)) {
        return NGX_DECLINED;
    }

    if (ngx_http_ns_test_bypass_all(r)) {
        return NGX_DECLINED;
    }
    
    cplcf = ngx_http_get_module_loc_conf(r, ngx_http_cookie_poisoning_module);
    
    if (cplcf->enabled != 1) {
        /* Cookie Poison not enabled */
        return NGX_DECLINED;
    }

    u = r->upstream;
    if (u) {
        part = &u->headers_in.headers.part;
    } else {
	    /* response from local */
        part = &r->headers_out.headers.part;
    }

    if (part == NULL) {
        /* Have no headers */
        return NGX_DECLINED;
    }

    memset(&cookie, 0, sizeof(ngx_str_t));
    memset(&cookie_name, 0, sizeof(ngx_str_t));
    memset(&neteye_cookie, 0, sizeof(ngx_str_t));

    h = part->elts;

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

            part = part->next;
            h = part->elts;
            i = 0;
        }

        if (h[i].key.len != strlen("Set-Cookie")) {
            continue;
        }

        if (!memcmp(h[i].key.data, "Set-Cookie", h[i].key.len)) {
            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                    "found set cookie");

            start = p = h[i].value.data;
            end = h[i].value.data + h[i].value.len;
            
            for (j = 0; j < h[i].value.len; j++, p++) {
                if (*p == ' ' || *p == '=') {
                    cookie_name.data = start;
                    cookie_name.len = p - start;

                    /* store this cookie's value to cookie */
                    if (*p == ' ') {
                        for (; *p != '='; p++) ;
                    }

                    p++;

                    cookie.data = p;

                    for (; *p != ';' && p < end; p++) ;

                    cookie.len = p - cookie.data;

                    if (cookie.len == 0) {
                        break;
                    }

                    cmp_len = cookie.len >= strlen("deleted") ? 
                        strlen("deleted") : cookie.len;

                    if (!strncmp((char *)cookie.data, "deleted", cmp_len)) {
                        /* update monitored cookies in session*/
                        ngx_http_cp_delete_monitored_cookies(r, &cookie_name);
                        break;
                    }

                    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
                            "cookie_name: %V, cookie_data: %V", 
                            &cookie_name, &cookie);
                    
                    /* md5 the cookie_data, and add it to the header */
                   
                    magic = ngx_random();
                    if (ngx_http_cp_gen_cookie_data(r, &cookie,
                                &neteye_cookie, magic)
                            != NGX_OK) {
                        return NGX_HTTP_INTERNAL_SERVER_ERROR;
                    }

                    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "neteye_cookie_data: %V",
                            &neteye_cookie);
                    
                    /* update monitored cookies in session*/
                    ngx_http_cp_update_monitored_cookies(r,
                            &cookie_name, &neteye_cookie, magic);

                    break;
                }
            }
        }
    }

    return NGX_DECLINED;
}