static ngx_int_t setup_default_servers(ngx_http_request_t *r, ngx_http_upstream_srv_conf_t *us) { ngx_http_upstream_available_capacity_srv_conf_t *conf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_available_capacity_module); if (conf->server_list) return NGX_OK; ngx_slab_pool_t *shpool = (ngx_slab_pool_t *)us->shm_zone->shm.addr; ngx_shmtx_lock(&shpool->mutex); ngx_http_upstream_available_capacity_server_t *prev_server_conf = NULL; size_t i = 0; for (i = 0; i < us->servers->nelts; ++i) { ngx_http_upstream_server_t *servers = us->servers->elts; ngx_http_upstream_available_capacity_server_t *server_conf = ngx_slab_calloc_locked(shpool, sizeof(ngx_http_upstream_available_capacity_server_t)); server_conf->server = &servers[i]; server_conf->capacity = 1; ngx_str_t server_address = ngx_string(server_conf->server->name.data); ngx_url_t url; ngx_memzero(&url, sizeof(ngx_url_t)); size_t server_address_size = strlen((char *)server_address.data); url.url.len = server_address_size; url.url.data = ngx_slab_alloc_locked(shpool, server_address_size); url.default_port = 80; ngx_cpystrn(url.url.data, server_address.data, server_address_size + 1); if (ngx_parse_url_slab(shpool, &url) != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "cannot parse url : %s", server_address.data); return NGX_DECLINED; } server_conf->addr = *url.addrs; server_conf->next = NULL; if (prev_server_conf) { prev_server_conf->next = server_conf; } else { conf->server_list = server_conf; } prev_server_conf = server_conf; } conf->server_num = us->servers->nelts; conf->search_start_peer = conf->server_list; ngx_shmtx_unlock(&shpool->mutex); return NGX_OK; }
static ngx_int_t ngx_dynamic_upstream_op_add(ngx_http_request_t *r, ngx_dynamic_upstream_op_t *op, ngx_slab_pool_t *shpool, ngx_http_upstream_srv_conf_t *uscf) { ngx_http_upstream_rr_peer_t *peer, *last; ngx_http_upstream_rr_peers_t *peers; ngx_url_t u; peers = uscf->peer.data; for (peer = peers->peer, last = peer; peer; peer = peer->next) { if (op->server.len == peer->name.len && ngx_strncmp(op->server.data, peer->name.data, peer->name.len) == 0) { op->status = NGX_HTTP_BAD_REQUEST; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "server %V already exists in upstream. %s:%d", &op->server, __FUNCTION__, __LINE__); return NGX_ERROR; } last = peer; } ngx_memzero(&u, sizeof(ngx_url_t)); u.url.data = ngx_slab_alloc_locked(shpool, op->server.len); if (u.url.data == NULL) { op->status = NGX_HTTP_INTERNAL_SERVER_ERROR; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to allocate memory from slab %s:%d", __FUNCTION__, __LINE__); return NGX_ERROR; } ngx_cpystrn(u.url.data, op->server.data, op->server.len + 1); u.url.len = op->server.len; u.default_port = 80; if (ngx_parse_url_slab(shpool, &u) != NGX_OK) { if (u.err) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s in upstream \"%V\"", u.err, &u.url); } op->status = NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_ERROR; } last->next = ngx_slab_calloc_locked(shpool, sizeof(ngx_http_upstream_rr_peer_t)); if (last->next == NULL) { op->status = NGX_HTTP_INTERNAL_SERVER_ERROR; ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to allocate memory from slab %s:%d", __FUNCTION__, __LINE__); return NGX_ERROR; } last->next->name = u.url; last->next->server = u.url; last->next->sockaddr = u.addrs[0].sockaddr; last->next->socklen = u.addrs[0].socklen; if (op->op_param & NGX_DYNAMIC_UPSTEAM_OP_PARAM_WEIGHT) { last->next->weight = op->weight; last->next->effective_weight = op->weight; last->next->current_weight = 0; } else { last->next->weight = 1; last->next->effective_weight = 1; last->next->current_weight = 0; } if (op->op_param & NGX_DYNAMIC_UPSTEAM_OP_PARAM_MAX_FAILS) { last->next->max_fails = op->max_fails; } else { last->next->max_fails = 1; } if (op->op_param & NGX_DYNAMIC_UPSTEAM_OP_PARAM_FAIL_TIMEOUT) { last->next->fail_timeout = op->fail_timeout; } else { last->next->fail_timeout = 10; } if (op->op_param & NGX_DYNAMIC_UPSTEAM_OP_PARAM_DOWN) { last->next->down = op->down; } peers->number++; peers->total_weight += last->next->weight; peers->single = (peers->number == 1); peers->weighted = (peers->total_weight != peers->number); ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "added server %V", &op->server); return NGX_OK; }