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;
}