10Sigor@sysoev.ru 20Sigor@sysoev.ru /* 30Sigor@sysoev.ru * Copyright (C) Igor Sysoev 40Sigor@sysoev.ru * Copyright (C) NGINX, Inc. 50Sigor@sysoev.ru */ 60Sigor@sysoev.ru 71394Sigor@sysoev.ru #include <nxt_router.h> 81394Sigor@sysoev.ru #include <nxt_http.h> 91394Sigor@sysoev.ru #include <nxt_upstream.h> 101394Sigor@sysoev.ru 111394Sigor@sysoev.ru 121394Sigor@sysoev.ru static nxt_http_action_t *nxt_upstream_handler(nxt_task_t *task, 131394Sigor@sysoev.ru nxt_http_request_t *r, nxt_http_action_t *action); 141394Sigor@sysoev.ru 151394Sigor@sysoev.ru 161394Sigor@sysoev.ru nxt_int_t 171394Sigor@sysoev.ru nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, 181394Sigor@sysoev.ru nxt_conf_value_t *conf) 191394Sigor@sysoev.ru { 201394Sigor@sysoev.ru size_t size; 211394Sigor@sysoev.ru uint32_t i, n, next; 221394Sigor@sysoev.ru nxt_mp_t *mp; 231394Sigor@sysoev.ru nxt_int_t ret; 241394Sigor@sysoev.ru nxt_str_t name, *string; 251394Sigor@sysoev.ru nxt_upstreams_t *upstreams; 261394Sigor@sysoev.ru nxt_conf_value_t *upstreams_conf, *upcf; 271394Sigor@sysoev.ru 281394Sigor@sysoev.ru static nxt_str_t upstreams_name = nxt_string("upstreams"); 291394Sigor@sysoev.ru 301394Sigor@sysoev.ru upstreams_conf = nxt_conf_get_object_member(conf, &upstreams_name, NULL); 311394Sigor@sysoev.ru 321394Sigor@sysoev.ru if (upstreams_conf == NULL) { 331394Sigor@sysoev.ru return NXT_OK; 341394Sigor@sysoev.ru } 351394Sigor@sysoev.ru 361394Sigor@sysoev.ru n = nxt_conf_object_members_count(upstreams_conf); 371394Sigor@sysoev.ru 381394Sigor@sysoev.ru if (n == 0) { 391394Sigor@sysoev.ru return NXT_OK; 401394Sigor@sysoev.ru } 411394Sigor@sysoev.ru 421394Sigor@sysoev.ru mp = tmcf->router_conf->mem_pool; 431394Sigor@sysoev.ru size = sizeof(nxt_upstreams_t) + n * sizeof(nxt_upstream_t); 441394Sigor@sysoev.ru 451394Sigor@sysoev.ru upstreams = nxt_mp_zalloc(mp, size); 461394Sigor@sysoev.ru if (nxt_slow_path(upstreams == NULL)) { 471394Sigor@sysoev.ru return NXT_ERROR; 481394Sigor@sysoev.ru } 491394Sigor@sysoev.ru 501394Sigor@sysoev.ru upstreams->items = n; 511394Sigor@sysoev.ru next = 0; 521394Sigor@sysoev.ru 531394Sigor@sysoev.ru for (i = 0; i < n; i++) { 541394Sigor@sysoev.ru upcf = nxt_conf_next_object_member(upstreams_conf, &name, &next); 551394Sigor@sysoev.ru 561394Sigor@sysoev.ru string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name); 571394Sigor@sysoev.ru if (nxt_slow_path(string == NULL)) { 581394Sigor@sysoev.ru return NXT_ERROR; 591394Sigor@sysoev.ru } 601394Sigor@sysoev.ru 611394Sigor@sysoev.ru ret = nxt_upstream_round_robin_create(task, tmcf, upcf, 621394Sigor@sysoev.ru &upstreams->upstream[i]); 631394Sigor@sysoev.ru if (nxt_slow_path(ret != NXT_OK)) { 641394Sigor@sysoev.ru return NXT_ERROR; 651394Sigor@sysoev.ru } 661394Sigor@sysoev.ru } 671394Sigor@sysoev.ru 681394Sigor@sysoev.ru tmcf->router_conf->upstreams = upstreams; 691394Sigor@sysoev.ru 701394Sigor@sysoev.ru return NXT_OK; 711394Sigor@sysoev.ru } 721394Sigor@sysoev.ru 731394Sigor@sysoev.ru 741563Svbart@nginx.com nxt_int_t 751394Sigor@sysoev.ru nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, 761394Sigor@sysoev.ru nxt_http_action_t *action) 771394Sigor@sysoev.ru { 781394Sigor@sysoev.ru uint32_t i, n; 791394Sigor@sysoev.ru nxt_upstream_t *upstream; 801394Sigor@sysoev.ru 811928Sz.hong@f5.com if (upstreams == NULL) { 821928Sz.hong@f5.com return NXT_DECLINED; 831928Sz.hong@f5.com } 841928Sz.hong@f5.com 851394Sigor@sysoev.ru upstream = &upstreams->upstream[0]; 861394Sigor@sysoev.ru n = upstreams->items; 871394Sigor@sysoev.ru 881394Sigor@sysoev.ru for (i = 0; i < n; i++) { 891394Sigor@sysoev.ru if (nxt_strstr_eq(&upstream[i].name, name)) { 901394Sigor@sysoev.ru action->u.upstream_number = i; 911394Sigor@sysoev.ru action->handler = nxt_upstream_handler; 921394Sigor@sysoev.ru 931597Shongzhidao@gmail.com return NXT_OK; 941394Sigor@sysoev.ru } 951394Sigor@sysoev.ru } 961563Svbart@nginx.com 971597Shongzhidao@gmail.com return NXT_DECLINED; 981394Sigor@sysoev.ru } 991394Sigor@sysoev.ru 1001394Sigor@sysoev.ru 1011394Sigor@sysoev.ru nxt_int_t 1021394Sigor@sysoev.ru nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, 1031394Sigor@sysoev.ru nxt_upstream_t ***upstream_joint) 1041394Sigor@sysoev.ru { 1051394Sigor@sysoev.ru uint32_t i, n; 1061394Sigor@sysoev.ru nxt_upstream_t *u, **up; 1071394Sigor@sysoev.ru nxt_upstreams_t *upstreams; 1081394Sigor@sysoev.ru nxt_router_conf_t *router_conf; 1091394Sigor@sysoev.ru 1101394Sigor@sysoev.ru router_conf = tmcf->router_conf; 1111394Sigor@sysoev.ru upstreams = router_conf->upstreams; 1121394Sigor@sysoev.ru 1131394Sigor@sysoev.ru if (upstreams == NULL) { 1141394Sigor@sysoev.ru *upstream_joint = NULL; 1151394Sigor@sysoev.ru return NXT_OK; 1161394Sigor@sysoev.ru } 1171394Sigor@sysoev.ru 1181394Sigor@sysoev.ru n = upstreams->items; 1191394Sigor@sysoev.ru 1201394Sigor@sysoev.ru up = nxt_mp_zalloc(router_conf->mem_pool, n * sizeof(nxt_upstream_t *)); 1211394Sigor@sysoev.ru if (nxt_slow_path(up == NULL)) { 1221394Sigor@sysoev.ru return NXT_ERROR; 1231394Sigor@sysoev.ru } 1241394Sigor@sysoev.ru 1251394Sigor@sysoev.ru u = &upstreams->upstream[0]; 1261394Sigor@sysoev.ru 1271394Sigor@sysoev.ru for (i = 0; i < n; i++) { 1281394Sigor@sysoev.ru up[i] = u[i].proto->joint_create(tmcf, &u[i]); 1291394Sigor@sysoev.ru if (nxt_slow_path(up[i] == NULL)) { 1301394Sigor@sysoev.ru return NXT_ERROR; 1311394Sigor@sysoev.ru } 1321394Sigor@sysoev.ru } 1331394Sigor@sysoev.ru 1341394Sigor@sysoev.ru *upstream_joint = up; 1351394Sigor@sysoev.ru 1361394Sigor@sysoev.ru return NXT_OK; 1371394Sigor@sysoev.ru } 1381394Sigor@sysoev.ru 1391394Sigor@sysoev.ru 1401394Sigor@sysoev.ru static nxt_http_action_t * 1411394Sigor@sysoev.ru nxt_upstream_handler(nxt_task_t *task, nxt_http_request_t *r, 1421394Sigor@sysoev.ru nxt_http_action_t *action) 1431394Sigor@sysoev.ru { 144*1954Sz.hong@f5.com nxt_upstream_t *u; 145*1954Sz.hong@f5.com 146*1954Sz.hong@f5.com u = r->conf->upstreams[action->u.upstream_number]; 147*1954Sz.hong@f5.com 148*1954Sz.hong@f5.com nxt_debug(task, "upstream handler: \"%V\"", &u->name); 149*1954Sz.hong@f5.com 150*1954Sz.hong@f5.com return nxt_upstream_proxy_handler(task, r, u); 1511394Sigor@sysoev.ru } 152